2017-03-17 6 views
0

関数内でパラメータが多すぎるという典型的な問題に直面しています。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キャッシュされたデータ。この問題への

知られている解決策は以下のとおりです。

  1. は、SRP違反を見てみましょう。私はそれがここのケースだとは思わない、少なくとも私は見ていない。
  2. は、新しいタイプの関連データをカプセル化し、インスタンスを渡すようにしてください。これは古典的な例ではfoo(x: Double, y: Double)foo(point: Point)に変換されるが、この場合には、私はカプセル化することができるもの(多分requestid)を特定することができず、各方法は、異なるシグネチャを持っているとして、それはタイプの爆発だろう明らかです。また、複雑さをAPIのコンシューマに変換し、メソッドごとに具体的なオブジェクトをインスタンス化する必要があります。
  3. 共通パラメータの型を作成し、方法に応じて、それを埋めるためにビルダーを使用するには、を呼び出しました。私はkeepAliveUntilcacheに送信して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)の問題ですか?

+0

5つのパラメータよりもデフォルト値(オプションの場合は '= nil')を指定すると、あまりに多くある必要はありません。しかし、オブジェクトにパラメータをラップすると、 ( 'get'、' delete'、 'cache' ...の代わりに)' method'を持つこともできる 'Request'と呼ばれるメソッドは古典的な解決法です。 – Sulthan

+0

これはプロトコルなので、デフォルトのパラメータを使用することはできません(それらを模倣するための解決策がありますが、それは優雅ではありません)。 – emenegro

+0

真。デフォルト実装を使用して拡張機能に追加する必要があります。 – Sulthan

答えて

1

ステップビルダパターンは、必要に応じて段階的にパラメータを追加する方法です。また、場合によっては必須のパラメータを定義できます(ポイント3で言及したように)。

単純化するには、ビルダーが持つ各パラメータ設定ツールのプロトコルを定義する必要があります。次はプロトコルチェーンを定義するため、各プロトコルはBuilder設定メソッドを定義し、シーケンス内の次のプロトコルを返します。最後に、ビルダーはすべてのプロトコルを実装する必要があります。このパターンを使用して

あなたが呼び出しシーケンスの代替パスを作成せ、ビルダーメソッドへの呼び出しの特定のシーケンスを定義します。

+1

ありがとう@Mario_io、これは私が探していたものです:)これは私のために新しい何かであるので、私はそれについての記事を書いた:https://medium.com/@mario.negro.martin/using-step-builder- pattern-in-swift-f8bd6ecd3677#.gxb94xz43 – emenegro

関連する問題