人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

『初めてのiOSアプリケーション』というアップルのドキュメントを読んでいるのですが、次の部分がわかりません。わかりやすく教えて下さい。

「Delegation」パターンはCocoa Touchアプリケーションでよく使われます。というのも、独自の振る舞いを実装するために、UIApplicationのような複雑なフレームワークオブジェクトのサブクラスを定義し、メソッドをオーバーライドする必要がないからです。

https://developer.apple.com/jp/devcenter/ios/library/documentation/iPhone101.pdf
21ページ

●質問者: Tats
●カテゴリ:コンピュータ
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● きゃづみぃ
●50ポイント

>「Delegation」パターンはCocoa Touchアプリケーションでよく使われます。

Cocoa Touchのアプリケーションを作成するに際に 「Delegation」パターンを使うことが多いです。


>というのも、独自の振る舞いを実装するために、UIApplicationのような複雑なフレームワークオブジェクトのサブクラスを定義し、メソッドをオーバーライドする必要がないからです。


「独自の振る舞いを実装するために」というのは、オリジナルで追加 および修正したい箇所のことです。

通常は フレームワークというものの サブクラスを定義したり
メソッドのオーバーライドをしたりして 作成しますが、
そういう必要性がない ということですね。

オーバーライドというのは フレームワークという プログラムの一部の関数などの
中身を そのまま 変更したりすることです。


Tatsさんのコメント
ふーむ。UIApplicationクラスのサブクラスをつくってメソッドをオーバーライドするのは、そんなに大変なことなのですか?

きゃづみぃさんのコメント
フレームワークを用いる場合、そのフレームワーク内の所作を理解していないと 作れません。 それが 大変なんだと思います。

Tatsさんのコメント
「フレームワーク内の所作」というのはどのようなことなのでしょう?すいません、気になったら理解しないと気が済まない性格なもので・・・単にサブクラスを作ってオーバーライドするだけならば、簡単だと思うのです・・・ん、それともデリゲーションではオーバーライドよりも簡単で、メソッドの既定の動作を全て継承(?)した上での追加事項のみを記述するだけで良い、ということでしょうか。

きゃづみぃさんのコメント
>「フレームワーク内の所作」というのはどのようなことなのでしょう? フレームワーク内でどのように 動いてるのかということです。 >ん、それともデリゲーションではオーバーライドよりも簡単で、メソッドの既定の動作を全て継承(?)した上での追加事項のみを記述するだけで良い、ということでしょうか。 質問の文章からは そこまでは わかりませんが・・・。 一応、オーバーライドとかしなくていいから 「Delegation」パターンが よく使われているよ ということですね。

きゃづみぃさんのコメント
あと http://marupeke296.com/DP_Delegate.html こちらも よく読んでみてください。

Tatsさんのコメント
むーーーうーーー2回読み返したんですが、なんだかわかりそうなんですがわからないです・・・クラスとメソッドを分離すると良いことがある、ぐらいまではわかったのですが・・・質問の件の場合はUIApplicationというクラスとそのメソッドを分離して、メソッドをデリゲートクラスに登録しているわけですよね。そうなると・・・何を考えなくて良くなるのでしょう?UIApplicationの中身だけでしょうか?すいません。

tdoiさんのコメント
拡張されることを意識したフレームワークであれば、サブクラス化してオーバーライドでもそれほど難しさは変わらないとは思います。ただ、必ずしも適切にそのような設計ができるとも限りません。 フレームワークのクラスとして、マウスのクリックを制御するonClickメソッドが実装されていたとします。 フレームワークとしては、onClickメソッドで、クリックされた領域が特定の領域ならウィンドウそのものをドラッグするし、また、別な特定の領域ならウィンドウ内の何かの動きを制御するし、また、他のところであれば、アプリケーションを終了する。というような処理をしていたとします。 ここで、あるアプリケーションでは特定の状況では、終了処理をできないようにしたいとします。 このような変更を想定をしたフレームワークを設計すると、とりあえず思いつくのは、 canFinish();メソッドみたいなのを用意しておいて、親クラスでは、必ずtrueを返しておき、必要があれば、サブクラス化してcanFinishをオーバーライドすればよいという方針です。 ただ、もう一方で、終了可能か判定するDelegateオブジェクトを登録する仕組みにしておくこともできます。この場合は、canFinishの実装が外に出ただけと言ってもいいでしょう。 で、Cocoaは後者のアプローチを使うことが多いよっていうのが、ここでの主張なのかと思います。 オーバーライドするのと、デリゲーションとどちらがよいかはケースバイケースなので、絶対にこちらが優位ということはないです。 強いてデリゲーションを使うメリットを挙げるとすると、プロトコルごとにオブジェクトにまとめることができるためにオブジェクトの意図が明確になるとともに、同様のケースでそのオブジェクトの再利用がしやすい可能性があります。この意図が明確というのは、この例でいえば、アプリケーションの終了だけを意識すればよいということです。親クラスで扱う操作は、アプリケーションの初期化や、その他様々な処理のオーバーライドをすることができますが、そういった要素に対する制御はこのDelegationオブジェクトは持ちえないので、意識しないでよいということです。 逆に言えば、これはサブクラス化の利点とも言ます。デリゲーションではプロトコルの境界を越えて制御することが難しいけれども、サブクラス化をした場合は、その辺りの自由度は高いと言えるでしょうね。自由度と複雑さはある種のトレードオフです。 質問に端的に言うならば、UIapplicationに登録できる特定のDelegationのプロトコルに実装を与えればよく、そのプロトコル以外のことは意識せずに実装できることが利点だと言ってるのでしょうね。

Tatsさんのコメント
なるほど・・・自由度と明確さのトレードオフなんですね。ふーむ、奥が深いですね。丁寧に説明していただいてありがとうございました。

2 ● a-kuma3
●50ポイント

継承よりも、委譲 (delegate) の方が柔軟なケースのひとつ。

振る舞いを変えようとしている対象のクラスが複数で、それぞれが継承関係にある場合。
例えば、「図形」を表すクラスがあったとします。
f:id:a-kuma3:20120517231343j:image

ここに、「影をつける」という機能追加をするときに、継承で実装するとしたら、どうなるでしょう。
継承関係の末端に、「影付き三角形」とか「影付き楕円」を実装することになるでしょう。

図形を描画する、という振る舞いを委譲で実装されている場合、こういうふうに実装できる余地があります。
f:id:a-kuma3:20120517231612j:image

図形の描画では、さまざまな修飾が行われるかもしれません。
それぞれの修飾の種類ごとに、その実装を、ひとつのクラスにカプセル化できるかもしれません。

修飾の種類が増えたらどうなるでしょう。
「影付き、回転可能な、背景画像が指定できる三角形」なんてのをいくつも作らなくちゃいけない?
「影をつける」、「回転する」、「背景画像をつける」というクラスに、処理を委譲できるかもしれません。


「図形を描画する」という処理を、図形の継承関係から外に出しているのを、
tdoi さんのコメントでは、「プロトコル」と表現しています。


でも、委譲で何でも解決できるでしょうか。
先の図形の例で言うと、描画に必要な情報は、基底の「図形」クラスから取得できないと実装できません。
また、回転させた図形の影はどうかきましょうか。
tdoi さんのコメントでの、「プロトコルの境界を越えて制御することが難しい」というのが、
この辺りの話になります。


委譲に関する質問だったので、委譲のメリットを推し出した書き方をしましたが、
継承には、それに向いたケースがあります。

GoF のパターンで言うと、Decorator や Chain of Responsibility が、委譲ならでは、のパターンで、
Template Method なんかが、継承のメリットを引き出したパターンになります。

関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ