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