11

ウィキペディアは「call super」をアンチパターンとして分類していますが、その理由はよくわかりません。このパターンは、objective-C/cocoa でかなり頻繁に使用されます。たとえば、init/dealloc、drawrect、awakefromnib などはすべて、super を呼び出す必要があります。ここで概念を誤解していますか?

記事へのリンク: http://en.wikipedia.org/wiki/Call_super

4

2 に答える 2

18

記事で述べられているように、アンチパターンであるスーパー メソッドを呼び出す必要があります。つまり、スーパー クラスは、機能を完全にするためにメソッドをオーバーライドすることを「期待」しますが、この期待を明示せずにオーバーライドします。また、スーパー実装を呼び出すことも想定しています。プログラムが機能するには、両方が必要です。

プログラマーの意図をコードから推測できないため、これはアンチパターンです。同僚がそれに取り組むことを決めた場合、彼らはクラスで何を期待しているのかわからないため、問題や苛立ちに遭遇する可能性があります.

したがって、メソッドの一部がオーバーライドされると予想されるが、他の部分はそのままにしておく必要がある場合は、テンプレート メソッド パターンを使用することをお勧めします。ここでは、置き換えてはならないすべてのものを 1 つの (プライベート) メソッドに保持します。次に、完全に別のものを呼び出します。これは、プログラムが機能するために実装する必要があります (一部の言語では、それ以外の場合はコンパイルさえしません)。こうすることで、重要なものをあるべき場所に残すことができ、クラスを拡張する人は誰でも何をすべきかを正確に知ることができますが、他の実装の詳細については幸いなことに無知のままです。

Objective-C には抽象メソッドや仮想メソッドはありませんが、スーパー メソッドが呼び出された場合に明示的に例外を発生させることで、同じ効果を得ることができます。そうすれば、同僚がメソッドをオーバーライドするのを忘れた場合、プログラムがクラッシュします。また、同僚が理解できるエラー メッセージが表示されてクラッシュします。これにより、同僚は問題をより迅速かつ簡単に理解して修正することができます。機能が完全ではないため、説明のない動作。

于 2012-12-21T16:57:42.770 に答える
4

問題の要点は次のとおりです。

..ただし、言語自体がこの呼び出しで規定されたすべての条件を強制できない可能性があるという事実が、これをアンチパターンにしています。

したがって、著者は、言語が彼らのためにすべきだと彼らが信じる何かをプログラマーがしなければならないことについて、肛門です。

ウィキペディアの記事Call Superに記載されている解決策は次のとおりです。

これらの問題を解決するためのより良いアプローチは、代わりにテンプレート メソッド パターンを使用することです。この場合、スーパークラスには、サブクラスによって実装され、元のメソッドがそのメソッドを呼び出す必要がある純粋な抽象メソッドが含まれます。

問題は、Objective-c に仮想関数がないことです。メッセージしかないので、ウィキペディアが提案するものを実装することはできません。

于 2012-12-21T17:00:57.270 に答える