web-dev-qa-db-ja.com

Objective-Cのプロトコルに対するプログラミング

[〜#〜] solid [〜#〜] の原則に遭遇しました。一つの燃える質問があります。常にプロトコルを使用する必要がありますか? Java開発者がそれらを使用する方法で誰かがそれらを使用するのを見たことはありません。

デモプロジェクトで試してみたところ、プロトコル用の.hファイルとヘッダー用の別の.hファイルができました。実装用の.mファイル、場合によってはUIの.xib。

ObjC開発者がデリゲートに対してのみプロトコルを使用する理由はありますか?テストファーストアプローチでObjCコードを見たことはありません。 SOLIDプログラミングはObjCに適用されますか?

3
zeiteisen

TDDはObjCの世界ではそれほど人気が​​ありません。公式のApple SDKライブラリのいくつかを見てください。TDD擁護者が嫌悪感をあきらめるようなパターンが見つかります(lotof singletons iOS SDKで、これはObjCで非常にうまく機能するパターンです。一般的にユニットテストもそれほど一般的ではないので、公式ユニットがテストスイートはXcodeの比較的最近のエディションであり、なぜそれがまだ3番目のレートであるのですか?ObjCの哲学は次のようです:

「テストを作成するためにコードを複雑にしないでください。単純なコードの方がデバッグが簡単です。」

それは間違いなくTDDの人たちを揺さぶるでしょうが、それは私がObjC開発者たちに指摘したアプローチです。

ObjCは、プロトコルに対して、Java開発者がインターフェースに対して行うよりも実用的なアプローチをとっています(「念のため、すべてのクラスにはインターフェースと実装が必要です!」)):

  • 同じインターフェースを持つ複数のクラスが必要であり、コンパイラーの助けが必要であることを知っている場合は、プロトコルを作成できます。
  • 同じインターフェースを持つ複数のクラスが必要であるがコンパイラからのサポートに関心がないことを知っている場合、「非公式プロトコル」を使用できます。 ( GKSessionオブジェクト からのデータを処理する方法を見てください:プロトコルではなくメソッドを実装します)。
  • おそらく1つのクラスのみを使用する場合は、そのクラスを使用してプロトコルを忘れてください。

これが、デリゲートと組み合わせて使用​​されるプロトコルのみを表示する傾向がある理由です。特にデリゲートパターンが非常に普及しているため、必要な機能を実装するために複数のクラスを作成する唯一の場所である傾向があります。他の言語では、追加機能を提供するために、インターフェースをサブクラス化してオーバーライドまたは実装する必要がある傾向があります。 ObjCは代わりにデリゲートを使用する傾向があります。

ObjCが動的であるという事実は、プロトコル/インターフェースの必要性の多くを取り除きます。 Java、C++、およびC#の開発者は、すべてを可能な限り正確に分類および入力することに多くの時間を費やしているため、多数のインターフェースおよびクラスが作成されています。これは、動的言語では必要ありません(そして、C#からObjCに切り替えたことをうれしく思う理由の1つです:型階層を記述する代わりに、問題の解決に時間を費やすことができます)。

ObjCは動的であり、 duck型付け をサポートしているため、オブジェクトがメソッド「quack」を実装している場合、「Duck」プロトコルに明示的に準拠せずにそのメソッドを呼び出すことができます。 ObjCの優れたメタプログラミング機能により、呼び出す前にオブジェクトがメソッドを実装しているかどうかを確認することもできます。

2
Ant

SOLIDの原則は、テクノロジーやプログラミング言語に関係なく、必ずしも必要ではありません。ただし、多くの開発者はそれらに従うことを選択し、Objective-Cでそれを行うことは確かに可能です。

Test-first Objective-Cに興味がある場合は、 BrowseOverflow をご覧ください。UIKitとネットワークサービスを利用する完全にテスト駆動型のアプリです。実際には、これを Test-Driven iOS Development のサンプルコードとして記述しましたが、原則に慣れている場合は、コードを見るだけで十分です。コードがテスト駆動であったとしても、プロトコルに溢れていないことがわかります。

その理由の1つは「ダックタイピング」です。 Objective-Cは、その前のSmalltalkやRubyの後は、実際にはオブジェクトのタイプを気にせず、メッセージを送信するだけです。タイプセーフティシステムは、コンパイラチェックに完全に制限されています。したがって、必要に応じて変数を具体的に入力することができ、still(場合によってはいくつかのキャストを使用)は、実行時に異なる型を提供します。両方の型が応答する限り、コードで渡されたメッセージに対して、すべてが機能します。BrowseOverflowのテストがこれを使用して、プロトコルを使用して型指定されていない変数に対しても、偽のテストを渡すことがわかります。

実際、歴史的なObjective-CとSmalltalk(および最新のRuby)では、多くの協調オブジェクトはまったく型付けされていません。Objective-Cでは、id型は「任意のオブジェクト」を意味します。これは現在ObjCではあまり一般的ではありませんが、Appleのフレームワークコードの多くは、これが標準であったときに存在していたほど古くなっています。新しいフレームワーク、および既存のフレームワークの新しいAPIは、非委任コラボレーターに対してより厳密な型指定とプロトコルタイプを使用していることに気づくでしょう。

ObjC開発者がデリゲートのプロトコルのみを使用する理由はありますか?

個人的な選択。そのアプローチに従う根本的な技術的理由はありません。

SOLIDプログラミングはObjCに適用されますか?

はい。むしろ、それは可能であり、多くの開発者はSOLIDの原則に従うことを選択します。

1
user4051