関数内でパラメータが多すぎるという典型的な問題に直面しています。Swift enumを使用して関数内のパラメータ数を減らす
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のコンシューマに変換し、メソッドごとに具体的なオブジェクトをインスタンス化する必要があります。 - 共通パラメータの型を作成し、方法に応じて、それを埋めるためにビルダーを使用するには、を呼び出しました。私は
keepAliveUntil
をcache
に送信してget
またはdelete
を送信しないと送信する必要があることを知っていますか?
スウィフトの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)の問題ですか?
5つのパラメータよりもデフォルト値(オプションの場合は '= nil')を指定すると、あまりに多くある必要はありません。しかし、オブジェクトにパラメータをラップすると、 ( 'get'、' delete'、 'cache' ...の代わりに)' method'を持つこともできる 'Request'と呼ばれるメソッドは古典的な解決法です。 – Sulthan
これはプロトコルなので、デフォルトのパラメータを使用することはできません(それらを模倣するための解決策がありますが、それは優雅ではありません)。 – emenegro
真。デフォルト実装を使用して拡張機能に追加する必要があります。 – Sulthan