design pattern: Proxy パターン
2025/05/13
今さら?と言われそうだが、まあそうだ。
デザインパターンは、知っていると「このパターンが使える」と思い出せるし、 人と話すときに「このパターンを使う」で通じる便利さだったりがあると思う。
読んでいる「クリーンコードクックブック」もそうで、class 名が “~Proxy” となっているので、 ああこれは Proxy パターンを使っているんだな、とわかる。
わかるのだが、名前しか知らない状態でサンプルコードを見ても、
Proxyパターンの説明をするコードではないので何だかわからん。
こちらがそのコードなのだが、interface
から継承した final class
が 2つあるだけで、
どちらも中身が空で済ませているのだ。
- Sources for Chapter 3 Anemic Models - 3.6 Removing DTOs
- 日本語版だとコメントも日本語になっている
空で済ませられるのがデザインパターンを知っているもの同士の利点だ。 無駄がなくてよろしい。
Proxy パターン
GoF 本の例からすると、interface
的なものを作っておき、呼び出し側はそれを使って呼び出す。
実際に呼び出すことになるインスタンスは、まあ最初に実装している間は最終的に呼び出す本物でもよいと思う。
試作を動かしていると、ちょっとこれは動きを変えたいときがあるぞ、ということがあったのだと思う。 本の例だと、エディタの途中に画像を差し込めるようにしたけど、最初から読み込んでしまうと重たくて無視できない、とか。
ただ、今から呼び出し側ががんばって画像を読み込むかどうか決めるようにするのも何だかなあぁぁぁ、と考えたのだろう。
せっかく画像を取得する class
があるんだから、それと同じ操作性を持つ class
を作って、
エディタからは新しく作った class
を呼び、呼び出された class
は必要に応じて最終的に呼び出す class
を使うようにしよう、とした。
そうすると、呼び出していたエディタの方はほとんど変更せずに済む。
元々画像データを返していた class
も変更せずに済む。
新しく中間に入った class
がちょっとがんばってダミーデータを返したり本物を返したりするだけだ。
もうすぐ表示しそうになったら画像を読み込むのか、別スレッドで画像読込を行って完了したものから表示可能にするのか、その辺はお任せだ。
大ざっぱにいえば、本来呼び出したい class
と似たような class
を間に挟むことで、
元の実装に大きくは変更を加えずに柔軟性を持たせることができる、ということになるか。
データの参照先がキャッシュになったり、ネットワークを経由するようになったり、みたいなときによさそうだ。
ただ、ものによっては proxy が膨れ上がりそうな気もする。
便利そうだから、何でもかんでも押し込んでしまったり。
まあ、そうなったらそうなったで仕方ないか。
proxy が別の proxy を呼び出す、みたいな構造になったりもしそうだけど、そういうのを言い出すと切りがない。
class
でなくても、関数呼び出しでそういうことはしばしばやる。
最初はローカルファイルだけしかやらないはずだったのに、どうしてもということで仕様変更になったとか。
予算の都合でやらんって言ったやん!みたいなのがひっくり返って、
しかもこっちは SES でやってるから予算とか関係なく働かんといかんし、
それによって単価が上がるわけでもないし、残業の上限を付けたいとか言いつつも
納期はどうのこうのとこっちに関係ない話ばかりして、まったくぶつぶつ。。。
はっ。
しかし、面倒なことを下に任せるという意味では、任せるって意味で delegate とか呼ばれてもおかしくないんじゃなかろうか。
C# にある delegate
は関数ポインタっぽいイメージだったが、検索すると Swift の話ばかり出てきた。
そういえば、Android のことを調べているときにそういうのが出てきたような。。。
delegate、じゃなくて delegation なのか。
記憶からすっかり抜けているし、読んでも記憶が甦らない。
by X
とした class
は、引数で与えられた X
と同じメソッドを持つことができるが、
オーバーライドすることもできる、というところか?
委譲というか、コピペして一部置き換え、みたいな感じだろうか。
イメージでは delegation = お任せ、だったのだけど、Proxy パターンの場合は「私が代わりにやっておくよ」ということで “proxy” なんだろう。