我正面臨函數中參數太多的典型問題。使用Swift枚舉來減少函數中的參數數量
protocol OfflineController {
func cache(request: OfflineRequestConvertible, forId id: String?, data: Data, keepAliveUntil keepAlive: Date?, completion: @escaping OfflineControllerCompletionHandler)
func get(request: OfflineRequestConvertible, forId id: String?, ifBefore before: Date?, completion: @escaping OfflineControllerCompletionHandler)
func delete(request: OfflineRequestConvertible, forId id: String?, completion: @escaping OfflineControllerCompletionHandler)
}
正如你可以看到它是一個普通緩存系統與功能cache
,get
緩存的數據和delete
緩存數據。
對這個問題的已知解決方案是:
- 看看SRP違規。我認爲這不是這種情況,至少我沒有看到。
- 嘗試封裝在新類型的相關數據,並通過一個實例。這是一個經典的例子
foo(x: Double, y: Double)
明確轉化爲foo(point: Point)
但在這種情況下,我不能確定什麼可以被封裝(也許request
和id
),並且這將是類型的爆炸,因爲每個方法都有不同的簽名。而且,它將複雜性轉化爲API的使用者,必須爲每個方法實例化一個具體對象。 - 創建一個共同參數類型和使用的助洗劑它取決於方法調用來填充。恕我直言,它掩蓋了API,我怎麼知道我要送
keepAliveUntil
執行cache
而不是get
或delete
什麼時候?
我在推遲Swift的enum
回憶這個問題的解決方案。現在,我想在這樣的事情:
enum OfflineControllerAction {
case cache(request: OfflineRequestConvertible, data: Data, id: String?, keepAliveUntil: Date?)
case get(request: OfflineRequestConvertible, id: String?, ifBefore: Date?)
case delete(request: OfflineRequestConvertible, id: String?)
}
protocol OfflineController {
func execute(_ action: OfflineControllerAction, completion: @escaping OfflineControllerCompletionHandler)
}
也許是更優雅,但我認爲這是非常相似點2,和我保持原來的方法在枚舉開關被分派。
問題是,您對這種解決方案有何看法?這是我不知道的另一種方法嗎?也許沒有解決方案,這只是一個設計問題(SRP)?
如果您提供默認值(例如'= nil' for optionals),那麼5個參數不必太多。然而,將這些參數包裝到一個對象中,例如所謂'Request',也可以有一個'method'(而不是'get','delete','cache' ...)是一個經典的解決方案。 – Sulthan
它是一個協議,所以我不能使用默認參數(有解決方案來模仿他們,但他們不優雅)。 – emenegro
是的。您將不得不使用默認實現將其添加到擴展中。 – Sulthan