LoginSignup
5
3

More than 5 years have passed since last update.

Proxy パターン

Posted at

Proxy パターンは、あるオブジェクトと同じように振る舞う代理クラスを用意する、という実装テクニックである。
代理クラスを用意するテクニックはいろいろなところで使われる。例えば、

  • String の代わりに HTMLString, RawString といったクラスを用意する
    • ユーザーが入力した文字列を直接表示してしまうことによる XSS 攻撃を防ぐ
  • Image の代わりに LazyImage クラスを用意し、実際に画像が必要になるまで読み込みを遅らせる
  • 本物のオブジェクトの代わりに Mock オブジェクトを使う
  • 実際のオブジェクトの代わりにそのオブジェクトの参照と参照カウンタを持つオブジェクトを使う
  • 読み込むのに時間がかかるデータを待たずに Future オブジェクトを返す
    • 代理人を用意するという点で Proxy パターンの亜種ではあるが、クラス図や振る舞いが異なるので同じパターンと言って良いかは微妙

クラス図

439px-Proxy_pattern_diagram.svg.png

実装例

String の代わりに HTMLString, RawString といったクラスを用意する

trait SmartString {
  def get: String
}

class RawString(val original: String) extends SmartString {
  def get: String = original
}

class HtmlString[T <: SmartString](val original: T) extends SmartString {
  lazy val escapedString = original.get
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")

  def get: String = escapedString
}

// 引数に HtmlString を指定することで、Escape されていない RawString が表示されるのを防ぐ
def showText[T <: SmartString](text: HtmlString[T]): Unit = {
  println(text.get)
}

val x = new RawString("<script>alert(\"this is raw string\");</script>")
val y = new HtmlString(x)

// showText(x)  // コンパイルエラー
showText(y)     // &lt;script&gt;alert(\"this is raw string\");&lt;/script&gt;

実装 in real world

他のパターンとの関係

  • Adaptor パターン
    • Adapter パターンは、既存クラスを変更することなくインターフェースを変えるテクニックである。
      • 同じ機能を持つ複数のサードパーティ製ライブラリを、ユーザーの好みで切り替えて使えるようにしたいが、インターフェースが各社バラバラで、サードパーティ製なのでインターフェースをいじれない。
      • そういった時に使えるデザインパターン
    • サードパーティ製ライブラリの「代わりに」使うという点で Proxy パターンと似ているが、本物クラスとプロキシクラスのインターフェースは共通していないという点で異なる。目的も違うので間違うことは少ないだろう
  • Decorator パターン
    • Decorator パターンは、既存クラスを変更することなく新たな機能を加えるテクニックである。
    • デコレートしたオブジェクトを、実際のオブジェクトの「代わりに」使うという点で、 Proxy パターンとよく似ている。
    • 目的が異なる
      • Decorator パターンは機能の追加に主眼をおいている
      • Proxy パターンは本物のオブジェクトが何らかの理由(負荷やまだ存在しない、など)で利用出来ない場合にその代理を行う
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3