オブジェクト指向プログラミングでは、委任とは、あるオブジェクト(受信側) のメンバー (プロパティまたはメソッド) を別の元のオブジェクト (送信側) のコンテキストで評価することを指します。委任は、送信側オブジェクトの責任を受信側オブジェクトに渡すことによって明示的に行うことができ、これは任意のオブジェクト指向言語で行うことができます。また、言語のメンバー検索ルールによって暗黙的に行うこともできますが、その機能に対する言語サポートが必要です。暗黙的な委任は、プロトタイプベースプログラミングで動作を再利用するための基本的な方法であり、クラスベースプログラミングにおける継承に相当します。言語レベルで委任をサポートする最も有名な言語は Self と JavaScript です。JavaScriptの委任を参照してください。
委任という用語は、オブジェクト間の様々な関係性についても、あいまいな意味で使用されます。詳しくは委任(プログラミング)を参照してください。よく混同される概念として、単に別のオブジェクトを使用すること(より正確にはコンサルテーションまたは集約)と、あるオブジェクトのメンバーを別のオブジェクトの対応するメンバーを評価することで評価すること(特に受信側オブジェクトのコンテキストで)があります。これはより正確には転送(ラッパーオブジェクトがラップされたオブジェクトに自身を渡さない場合)です。[ 1 ] [ 2 ] [ a ]委任パターンは委任を実装するためのソフトウェア設計パターンですが、この用語はコンサルテーションや転送にもあいまいな意味で使用されます。
概要
[編集]いわゆる自己呼び出しをディスパッチするためのメソッド検索ルールを利用するプログラミング言語機能としてのこの委任の感覚は、1986 年の論文「オブジェクト指向システムで共有動作を実装するためのプロトタイプ オブジェクトの使用」でLiebermanによって定義されました。
委任は動的バインディングに依存しており、特定のメソッド呼び出しが実行時に異なるコードセグメントを呼び出すことができることが必要である[引用が必要]。これは、プログラムコンポーネントの動作をカスタマイズする手段として、macOS(およびその前身であるNeXTStep )全体で使用されています。 [ 3 ]クラスはプログラム固有のデリゲートを受け取り、必要に応じてデフォルトの動作をオーバーライドできるため、単一の OS 提供クラスを使用してウィンドウを管理するなどの実装が可能になります。たとえば、ユーザーが閉じるボックスをクリックすると、ウィンドウマネージャーはデリゲートに windowShouldClose: 呼び出しを送信し、デリゲートは、ウィンドウの内容によって表される未保存のデータがある場合、ウィンドウを閉じるのを遅らせることができます。
委任は、自己の遅延バインディングとして特徴付けられる(転送とは区別される): [ 4 ]
...親の
self(またはthis) 変数に送信されたメッセージは、メッセージを最初に受信したオブジェクトに「戻ります」。
つまり、self受信側オブジェクトのメソッド定義は、定義時 (コンパイル時や関数がオブジェクトにアタッチされたときなど) にそのオブジェクトに静的にバインドされるのではなく、評価時に元のオブジェクトにバインドされます。
プログラムコードの可読性と理解性を向上させるために、継承よりも委任の方が好ましい場合もあると議論されている[ 5 ]。明示的な委任は広く普及しているにもかかわらず、継承の代替モデルとして委任を実装している主要プログラミング言語は比較的少ない。委任と継承の正確な関係は複雑であり、両者を同等とみなす研究者もいる。あるいは、一方が他方の特殊なケースであると考える者もいる[ 6 ] 。
委任のための言語サポート
[編集]メソッド検索規則による委譲をサポートする言語では、メソッドのディスパッチは継承における仮想メソッドの定義と同様に定義されます。つまり、メソッド検索では常に最も具体的なメソッドが選択されます。したがって、たとえ制御が他のオブジェクト(オブジェクト参照ではなく委譲リンク経由)に渡されていたとしても、メソッド検索の開始点は 元のレシーバーエンティティとなります。
委任には、実行時に実行でき、特定の型のエンティティのサブセットのみに影響を与え、実行時に削除することさえできるという利点があります。これに対し、継承は通常、インスタンスではなく型を対象とし、コンパイル時にのみ実行されます。また、継承は静的に型チェックできますが、委任は一般的にジェネリックなしでは型チェックできません(ただし、限定された委任バージョンは静的に型安全になる場合があります[ 7 ])。委任は「特定のオブジェクトの実行時継承」と呼ばれることもあります。
以下はC# / Javaのような言語での疑似コードの例です。
class A { void foo () { // "this" は他の言語では "current"、"me"、"self" という名前でも知られていますthis . bar (); }
void bar () { print ( "a.bar" ); } }
class B { privateデリゲートA a ; // 委任リンク
パブリックB ( A a ) { this . a = a ; }
void foo () { a . foo (); // aインスタンスでfoo()を呼び出す}
void bar () { print ( "b.bar" ); } }
a = new A (); b = new B ( a ); // 2つのオブジェクト間の委任を確立する
を呼び出すと、 は のコンテキスト内で元の受信オブジェクトを参照するため、 b.barb.foo()が出力されます。 の結果として生じる の曖昧性は、オブジェクト統合失調症と呼ばれます。
thisbathis
暗黙的な をthis明示的なパラメータに変換すると、 の呼び出し (デリゲートBを使用した内)は に変換されます。メソッド解決にはの型が使用されますが、引数にはデリゲート オブジェクトが使用されます。
aa.foo()A.foo(b)abthis
継承を使用した場合の類似のコード (解決がオブジェクトではなくクラスに基づいていることを強調するために大文字を使用) は次のようになります。
クラス A { void foo () { this . bar (); }
void bar () { print ( "A.bar" ); } }
クラス BはAを拡張します{ public B () {}
void foo () { super . foo (); // スーパークラス (A) の foo() を呼び出す}
void bar () { print ( "B.bar" ); } }
b =新しいB ();
を呼び出すとB.barb.foo()が返されます。この場合、は明確です。単一のオブジェクト が存在し、サブクラスの メソッド に解決されます。
thisbthis.bar()
一般的にプログラミング言語は、この珍しい形式の委任を言語概念としてサポートしていませんが、いくつかの例外があります[引用が必要]。
二重継承
[編集]言語が委譲と継承の両方をサポートしている場合、両方のメカニズムを同時に利用することで 二重継承を行うことができます。
クラス CはA { delegationlink D d ; }を拡張します。
これにより、メソッド検索に追加のルールが必要になります。これは、検索パスが 2 つあるため、最も具体的であると指定できるメソッドが 2 つある可能性があるためです。
関連分野
[編集]委任は、エンティティ間でコードとデータを共有するための低レベルのメカニズムと説明できます。したがって、他の言語構成要素の基盤となります。特にロール指向プログラミング言語は委任を活用してきましたが、特に古い言語では、委任を使用していると主張しながら、実際には集約が使用されていました。これは不正行為ではなく、単に委任の意味を複数形で定義しているだけであり、前述の通りです。
最近では委任の分散化に関する研究も行われており、たとえば検索エンジンのクライアント (安いホテルの部屋を探す) は委任を使用して共有エンティティを使用し、ベスト ヒットや一般的な再利用可能な機能を共有できます。
委任は、 2003 年に Ernst と Lorenz によって、 アスペクト指向プログラミングにおけるアドバイス解決にも提案されました。
参照
[編集]区別する:
注記
[編集]- ^ Beck 1997 では、受信オブジェクトが送信オブジェクトにアクセスできない場合を「単純委任」、受信オブジェクトが送信オブジェクトにアクセスできる場合を「自己委任」と呼んでいます。現代の言葉で言えば、この記事ではこれらを「転送」と「委任」と呼んでいます。
参考文献
[編集]- ^ ガンマ他1995、「委任」20~21頁。
- ^ ベック 1997、「委任」、64~69ページ。
- ^ Apple (2009年8月20日). 「Cocoa基礎ガイド:デリゲートとデータソース」 . Apple Developer Connection . 2009年9月11日閲覧。
- ^ 「交差するクラスとプロトタイプ」。システム情報学の展望:第5回国際アンドレイ・エルショフ記念会議、PSI 2003、アカデムゴロドク、ノボシビルスク、ロシア、2003年7月9日~12日、改訂論文。38 ページ。
- ^ [1] Trygve Reenskaug、オスロ大学情報学部、「読みやすいコードのためのケース」(2007年)
- ^ Stein, Lynn Andrea.委任は継承である. OOPSLA '87 オブジェクト指向プログラミングシステム、言語、アプリケーションに関する会議議事録. pp. 138– 146. doi : 10.1145/38807.38820 .
- ^ Günter Kniesel (1999-11-19). 「実行時コンポーネント適応のための型安全な委譲」 . ECOOP' 99 — オブジェクト指向プログラミング. コンピュータサイエンス講義ノート. 第1628巻. Springer. pp. 351– 366. CiteSeerX 10.1.1.33.7584 . doi : 10.1007/3-540-48743-3_16 . ISBN 978-3-540-66156-6. オリジナルから2015年3月4日にアーカイブ。 2015年3月4日閲覧。
本論文では、純粋な転送ベースのオブジェクト構成を補完するものとして、オブジェクトベースの継承(委任とも呼ばれる)を提案する。クラスベースのオブジェクトモデルへの委任の型安全な統合を提示し、それが転送ベースのコンポーネント相互作用が直面する問題をどのように克服するか、コンポーネントの独立した拡張性と予期せぬ動的なコンポーネント適応をどのようにサポートするかを示す。
{{cite book}}: CS1 maint: bot: 元のURLステータス不明(リンク)
- リーバーマン、ヘンリー(1986). 「プロトタイプオブジェクトを用いたオブジェクト指向システムにおける共有動作の実装」 .オブジェクト指向プログラミングシステム、言語、アプリケーションに関する会議論文集. 第21巻. ポートランド. pp. 214– 223. CiteSeerX 10.1.1.48.69 . doi : 10.1145/960112.28718 .
{{cite book}}:|journal=無視されました (ヘルプ)CS1 メンテナンス: 場所の発行元が見つかりません (リンク) - リン・アンドレア・スタイン、ヘンリー・リバーマン、デイヴィッド・ウンガー:共有の共有観:オーランド条約. ウォン・キム、フレデリック・H・ロホフスキー編:オブジェクト指向概念、データベース、およびアプリケーションACM Press、ニューヨーク、1989年、第3章、31~48ページISBN 0-201-14410-7(Citeseerでオンライン)
- ガンマ、エリック、ヘルム、リチャード、ジョンソン、ジョン・ブリシデス(1995). 『デザインパターン:再利用可能なオブジェクト指向ソフトウェアの要素』 .アディソン・ウェズリー. ISBN 978-0-201-63361-0。
- Malenfant, J.: 委任ベースのプログラミング言語の意味的多様性について、OOPSLA95 会議論文集、ニューヨーク: ACM 1995、pp. 215–230。
- ベック、ケント(1997年)『Smalltalkベストプラクティスパターン』プレンティス・ホール、ISBN 978-0134769042。
- カスパー・ビルステッド・グラヴァーセン:「役割の本質――言語構成概念としての役割の分類学的分析」博士論文 2006年(コペンハーゲンIT大学オンライン)
外部リンク
[編集]- C++でデリゲートを実装する新しい方法
- C++ の高速デリゲート
- PerfectJPatternオープンソースプロジェクト、Javaでデリゲートの再利用可能な実装を提供します