ねらい
- あるオブジェクトの代理やプレースホルダを提供し、アクセス制御を実現する
AKA
- Surrogate
モチベーション
-
ドキュメントエディタ上の画像オブジェクトの例
- 画像はコスト高い
- 最初から全部は見えてないので、最初に全部読み込む必要はない
- 見えるようになってから読み込めばいい
- 画像を遅延初期化することにより・描画・テキスト成形のロジックに影響が及ぶべきではない
-
画像のプロキシ
ImageProxy
を導入することで解決する- 利用側からは画像オブジェクトと区別がつかない(同じインターフェース)
- 画像オブジェクトの初期化の責務を担う
-
幅高さ情報ももつ
- 画像オブジェクト読み込み前はとりあえず0とかを返す
- 読み込み後は、画像の幅高さを返す
つかいどころ
Remote Proxy
- 異なるアドレス空間のオブジェクトを仲介するプロキシ
-
Ambassador (大使)とも
- 国境をまたぐイメージからか
Virtual Proxy
- 遅延生成・遅延初期化を行うプロキシ
Protection Proxy
- アクセス制御を行うプロキシ
Smart Reference
- 裸のポインタを置き換えるもの
-
例
-
std::shared_ptr<T>
- 参照カウント、0になったら解放
- 永続データのアクセサ (DAO: Data Access Object)
-
排他制御つきのアクセサ
- なんか名前あるんだろうか
-
登場人物
-
Proxy
RealSubject
への参照を保持するRealSubject
とSubject
とのインタフェースが一致していれば
(=RealSubject
のインタフェースがSubject
のスーパーセットでなければ)
Subject
への参照を保持することもある-
Subject
インタフェースを実装するRealSubject
と置換できるよう
RealSubject
へのアクセス制御や、生成・初期化・解放の責務を負う-
種類別の責務
-
Remote Proxy
-
異なるアドレス空間に要求を仲介する
- リクエストや引数の変換等を伴う
-
-
Virtual Proxy
-
RealSubject
オブジェクトの生成を遅延させられるよう、
追加の情報をもつことがあるImageProxy
の幅高さ0、など
-
-
Protection Proxy
- 呼び元の認可
-
-
Subject
RealSubject
とProxy
に共通のインタフェースを与える
-
RealSubject
Proxy
が代理をつとめる対象のオブジェクトのクラス
クライアントコードからの利用
- クライアントコードは
Subject
に対して操作を行う -
Proxy
はこれを受け取り、RealSubject
に良しなに仲介する- 「良しなに」は
Proxy
の種類によりけり
- 「良しなに」は
結果
-
中間層が1つ追加されることにより・・・
-
Remote Proxy
- オブジェクトが別のアドレス空間にあることを隠蔽できる
-
Virtual Proxy
- 遅延生成・遅延初期化できる
-
Protection Proxy/Smart Reference
-
オブジェクトアクセスの前後でなんかできる
- アクセス拒否
-
参照カウント
- カウント0でオブジェクト解体・メモリ解放
-
-
-
copy-on-write
- 巨大なオブジェクトのコピーで有用
-
実際にコピーが必要になるまで、複製処理を遅延する
- modificationが生じないかぎり不必要
- Virtual ProxyとSmart Referenceとの合わせ技といえるかも
実装にあたり考えるべきこと
言語の機能を使うと幸せになれることも
演算子オーバーロード
-
C++の
->
とか*
とか- Virtual Proxyなんかで有用
- Protection Proxyのように、一部の操作のみ
RealSubject
に取り次ぎたいような場合には不適切
マジックメソッド(って一般的なワードなんだろうか)
-
未定義のメソッドが呼び出されたときに呼ばれるやつ
- Smalltalkの
doesNotUnderstand:
- PHPの
__call()
- Smalltalkの
-
doesNotUnderstand:
の弱点-
言語組み込みの一部の操作については呼ばれない
==
演算子とか
- もともと例外処理用であり、速度が遅い
-
- 無限再帰に注意する
Proxyが包むオブジェクトの型
RealSubject
はSubject
派生なので、インタフェースはスーパーセットになる-
インタフェースが一致していれば、
Proxy
はSubject
を集約してもいい- すべての
RealSubject
やProxy
でさえも一様に扱える
- すべての
- Virtual Proxy等、特定の
RealSubject
をインスタンシエートしなければならない場合は、その具象クラスのオブジェクトを集約する
関連するパターン
-
Adapterとの対比
Adapter
は、Adaptee
と異なるインタフェースを提供する-
Proxy
は、基本的にRealSubject
と同じインターフェースを提供するが、
Protection Proxyはこの限りではない- 操作を認可しない場合、インタフェースはサブセットになる
-
Decorator
-
実装は似ているが目的が異なる
- Decorator: インタフェースをそのままに、オブジェクトに責務を追加する
- Proxy: オブジェクトのアクセス制御を行う
- 【所感】というか集約のパターンの実装はどれも似たり寄ったりだと思う
-
Proxyの種類によっては、実装が似通わなくなるケースもある
-
Remote Proxy
-
オブジェクトそのものの参照はもたず、間接的な参照をもつ
- 「ホストIDとローカルアドレス」とか
-
-
Virtual Proxy
-
最初はオブジェクトそのものの参照はもたず、間接的な参照をもつ
- ファイル名とか
-
-
-
英語
-
Ambassador
-
大使
- 国をまたぐ代理人、というかんじ
- こういう比喩すき
-
-
Housekeeping
-
【計算機】後始末処理
Dispose()
とか
-