委譲(Delegation)とは
委譲とは、
オブジェクト指向プログラミングにおいて、あるオブジェクトの操作を別のオブジェクトに代替させる手法です。これにより、オブジェクトは自身の処理の一部を他のオブジェクトに任せることができ、コードの柔軟性と再利用性を高めることができます。
概要
委譲を行うオブジェクト(委譲元)は、委譲先のオブジェクトへの参照を持ちます。委譲元は、必要に応じてこの参照を切り替えることで、様々な動作を実現できます。これは、一種の実装遅延やプラグイン機構と見なすことができます。
例えば、オブジェクトの編集処理において、編集の前処理や後処理を別のオブジェクトに委譲することで、オブジェクト本体の変更を最小限に抑え、コードの局所性を向上させることが可能です。
代理(Proxy)との違い
操作の代替という点で、代理(Proxy)と呼ばれる手法もあります。しかし、代理は、代理側のオブジェクトが実体への参照を保持し、操作のフィルタリングを行うことを目的としています。一方、委譲は実装の分離を主な目的としており、その点が異なります。
インターフェースとの関連
委譲先のオブジェクトは、どのような操作を実装すべきかを知っている必要があります。そのため、委譲はインターフェースと組み合わせて利用されることが多いです。これにより、委譲先のオブジェクトが特定のインターフェースを実装していれば、委譲元は委譲先の具体的な実装を意識せずに処理を委譲することができます。
言語ごとの実装
委譲は、多くの
オブジェクト指向プログラミング言語でサポートされており、デザインパターンとして活用されたり、言語機能として組み込まれたりしています。例えば、以下の言語で委譲がどのように実装されているかを見てみましょう。
C++では、委譲を直接サポートする言語機能はありませんが、オブジェクトへの参照やポインタを利用して実装できます。
Javaも同様に、委譲を直接サポートする機能はありませんが、インターフェースと参照を組み合わせることで実現できます。
JavaScriptのようなプロトタイプベースの言語では、プロトタイプ機能を用いて、委譲と継承の中間のような動作を簡単に実現できます。プロトタイプを書き換えることはできませんが、委譲先のオブジェクトを容易に指定できます。
Objective-Cでは、デリゲートという概念で委譲を実現します。デリゲート先のオブジェクトはどんなオブジェクトでも構いません。デリゲート先に必要なメソッドがなくてもコンパイルエラーにはならず、実行時に何も実行されないだけです。
Objective-Cでは、委譲は一般的な実装パターンとして広く利用されています。
例えば、ウィンドウの処理を別のオブジェクトに委譲する場合、ウィンドウオブジェクトのデリゲートを設定することで、ウィンドウのイベントを別のオブジェクトで処理できます。
objectivec
[mainWindow setDelegate:self];
この例では、`self` (自身) にウィンドウのデリゲートを設定しています。これにより、ウィンドウが閉じられる前に何か処理を行いたい場合、`self` オブジェクトに `windowWillClose` メソッドを実装しておけば、ウィンドウのクラスを変更せずに振る舞いをカスタマイズできます。
Smalltalk
Smalltalkでは、メッセージ機構を利用して委譲を行うことができます。オブジェクトにメッセージが送られた際に、そのオブジェクトに該当するメソッドがない場合、`doesNotUnderstand:` メソッドが呼ばれます。このメソッド内で受け取ったメッセージを他のオブジェクトに転送することで、委譲を実現できます。
Objective-Cにも同様の仕組みがあります。
Go
Go言語では、委譲を直接サポートする構文があります。Go言語は継承の機能を持っていませんが、委譲構文により継承と同様の機能を実現できます。例えば、多重継承も可能ですが、基底型から派生型のメンバーを呼び出すことはできません。
go
type Line struct { /
.../ }
type Bezier struct { /
.../ }
type DrawableLine struct {
Line
Bezier
}
この例では、 `DrawableLine` 型に `Line` と `Bezier` の機能が委譲されています。
Ruby
Rubyでは、標準添付の delegate ライブラリを使って委譲を利用できます。
プロトタイプベース言語における委譲
プロトタイプベースの言語(
JavaScriptやSelfなど)では、クラスの代わりにプロトタイプオブジェクトを用いてオブジェクトを生成します。このプロトタイプオブジェクトが委譲先となり、新しいオブジェクトはそのプロトタイプの機能を受け継ぎます。
まとめ
委譲は、
オブジェクト指向プログラミングにおける重要な概念であり、コードの柔軟性、再利用性を高めるための強力なツールです。委譲の概念を理解し、適切に活用することで、より保守性の高いコードを書くことができるでしょう。
関連項目
デザインパターン)
デリゲート (プログラミング))
*
トレイト