ははデリゲートパターンです。代理人のプロパティは、より一般的なdelegate
の名前ではなく、単にclass1Obj
と呼ばれます。ここでの重要な問題は、プロトコルを使用していないことです。その結果、これらの2つのクラスは「密接に結合」されています。つまり、Class2
はClass1
の実装の詳細に大きく依存します。さらに、これら2つの緊密に結合されたクラスでは、のどのメソッドが必要かもしれないかはすぐには分かりません。 Class2
の動作を壊すような変更を誤って行うことが容易になるため、Class1
のメンテナンスが難しくなります。 Class1
以外のクラスと組み合わせてClass2
を使用することも難しくなります。
代わりに、Class2
とそれを使用する必要があるかもしれない他のオブジェクトの間のコントラクトの性質を正確に明確にするプロトコルを宣言します。その結果、クラスは密接に結合されていない。すなわち、Class2
は、問題のプロトコルへの適合に加えて、他のクラスについて何も知る必要がない。さらに、Class1
を編集するときに、プロトコルに準拠するように宣言すると、必要なメソッドやプロパティを実装しなかったときに警告が表示されます。
このように、プロトコルは無視できない量の作業で、コードを維持しやすくします。また、Class2
とClass1
以外のものを組み合わせて使用することもできます。
ボトムラインのプロトコルでは、保守が簡単で柔軟性の高いコードが生成され、隠された前提はありません。
デリゲートプロトコルのパターンを使用しない場合は、別の代替はClass1
がClass2
が呼び出すことができることを、コードのブロックを提供するクロージャを、使用することです。あなたは二つのクラスの間の非常にシンプルなインターフェイスを持っているときに、二つのクラス間の豊富なインタフェース、この閉鎖パターンを持っている場合、デリゲートプロトコルパターンが有用であるが
class Class1 {
var class2Obj = Class2()
init() {
class2Obj.handler = { [weak self] in // note `weak` reference which avoids strong reference cycle
self?.class1Method()
}
}
func class1Method() {
print("Parent")
}
}
class Class2 {
var handler: (() -> Void)?
func class2Method() {
handler?()
}
}
:だからあなたのような何かを行うことができます。
上記のより一般的な順列は、がClass2
で開始する特定の要求とより直接関連している場合です。したがって、パラメータをClass2
の適切なメソッドのクロージャにするだけです。さらに、あなたは頻繁にデータを渡すので、我々はオプションString
をバック渡していることを想像している:これらの閉鎖パターン
class Class1 {
var class2Obj = Class2()
func performClass2Method() {
class2Obj.class2Method { string in
guard let string = string else { return }
self.class1Method()
}
}
func class1Method() {
print("Parent")
}
}
class Class2 {
func class2Method(completionHandler: @escaping (String?) -> Void) {
// do something which creates `string`
// when done, call the closure, passing that `string` value back
completionHandler(string)
}
}
オブジェクト間の単純なインターフェースを行うための素晴らしい方法を、だけでなく、非常に緩く2つのクラスを保持します結合された(すなわち、Class2
はClass1
に依存しません)、デリゲートパターンでプロトコルを使用するのとほとんど同じです。しかし、うまくいけば、上記の閉鎖の例は、リッチデリゲートプロトコルパターンの単純な代替案を示しているはずです。
出典
2017-01-22 01:43:47
Rob
はい、このように通信できます。しかし、デリゲート、ブロック、クロージャは、他の人がClass2が "メソッド"をコールバックすることを理解することがより理解できます。これは「ベストプラクティスは何か」の問題です: –
@YunCHEN - はい、クロージャーパターンも使用できますが、クロージャーを使用することが「ベストプラクティス」であると主張する資格があります。単純なケースでは、クロージャーが便利かもしれませんが、より豊かなインターフェースでは、デリゲート・プロトコルのパターンはしばしば優れていますが、インターフェースの性質にもよりますが、 2つの密接に結合されたクラスのAnshuのパターンは最適ではありません。 – Rob
@Rob、あなたと同意します。 –