GoF本 Discussion of Behavioral Patterns

GoFデザインパターン勉強メモ

変化するものをカプセル化する

  • ここでは「カプセル化する」 = 「同じインターフェースを与えて抽象化する」くらいの意味合い

    • Strategy

      • アルゴリズムをカプセル化
    • State

      • 状態依存の振る舞いをカプセル化
    • Mediator

      • オブジェクト間の相互作用をカプセル化
    • Iterator

      • オブジェクト内部の走査をカプセル化
  • 「同じインターフェースを与える」ための新しいクラス・オブジェクトを導入する

    • Chain of Responsibilityのように、既存のクラス・オブジェクトで済ますこともある
    • 元々あったオブジェクト自身は仕事をせず、処理を委譲するようになる
  • オブジェクト間の相互作用は必ずしも静的にはきまらない

    • Chain of Responsibilityでは、リクエスト受信候補オブジェクトは動的にいくらでも増やせる

引数としてのオブジェクト

  • (動的)ポリモーフィズム

    • Visitor

      • visitor, elementの両方の型により処理がきまる
  • ブラックボックス

    • Command

      • 「誰にどんなリクエストが飛ぶか知らないが、Execute()で実行できる」
      • これもポリモーフィズム
    • Memento

      • 「中身は知らないが、Originatorの状態を復元するための情報が詰まっている」
      • これはポリモーフィズム関係ない

一元管理か分散か

  • MediatorとObserverとは競合するパターン

    • 珍しい
Mediator Observer
オブジェクト間の連絡 一元管理 分散
束縛条件 Mediator一元管理 ObserverとSubjectとで形成
再利用 大変 容易
処理の追いやすさ 容易 大変

リクエストの送信/受信の疎結合化

  • 密結合だとまずい

    • 上位モジュールが下位モジュールを叩く、というレイヤー構造が台無しになる
    • モジュール間に相互依存あると、単体で再利用できなくなる
  • 以下、疎結合にするパターン。それぞれ特徴がある

    • Command

      • CommandのInvokerがsender
      • command->Execute()の中でreceiver->Action()する
      • 1 sender - 1 receiver
    • Observer

      • 出版-購読モデルともいうくらいで、基本的に 1 sender (Subject) - 多 receiver (Observer)

        • 1つのObserverが複数のSubjectを観測することもある
      • 状態の変化を通知
      • データに依存関係がある場合に適している

        • 【補】ModelとViewsとか
    • Mediator

      • 多 sender - 多 receiver
      • 各Colleagueがsenderでありreceiverである
      • が、直接はやりとりせず、Mediatorを経由する
      • やはり状態の変化を通知
      • システムのカスタマイズが容易になる

        • Mediatorだけ派生すればよいため
      • Mediatorがsenderを引数に受け取って何かする場合、型安全性に注意

        • 【補】引数型によるディスパッチができない場合、型フィールドによる分岐やダウンキャストを伴う
          MediatorをVisitorに、ColleagueをElementにすれば回避可能
    • Chain of Responsibility

      • 1 sender - any receiver
      • 新しいクラスやオブジェクトを追加する必要がない
      • 実装によっては型安全性に注意

        • 【補】引数型によるディスパッチができない場合、型フィールドによる分岐やダウンキャストを伴う
          ResponseをCommandにすれば回避可能

併用

振る舞いのパターン同士

  • Template Method

    • あらゆるパターンと併用される
  • Chain of ResponsibilityとCommand

    • RequestをCommandにする
  • InterpreterとState

    • Contextに状態をもたせる?

      • 【補】例) JavaScriptの構文解析で、strictモードかどうか

振る舞いのパターンと他の

  • VisitorとComposite

    • visit対象のオブジェクト構造がComposite
  • Chain of ResponsibilityとComposite

    • CompositeのあるComponentから、Composite全体としてのプロパティにアクセスできるようにする?

      • 【補】例) DOM

        • Nodeはマウスオーバーされたら、「マウスカーソルの形を決めてください」とリクエストをエスカレーションする
        • 祖先要素のCSSにcursorが指定されていたらそれを使用し、エスカレーションを止める
        • 実際そういうアルゴリズムなのかは知りません
  • DecoratorとComposite

    • 【補】例) お絵描きソフト

      • 基本図形(Leaf)を組み合わせた複雑な図形(Composite)にマージンやボーダーをつける
  • ObserverとComposite

    • あるオブジェクト構造が変化したら、別のオブジェクト構造も追従させる
  • StateとComposite

    • 【補】例) DOM

      • CSSのdisplay属性に対応したDisplayStateを定義する
      • DisplayStateに応じて描画のしかたが変わってくる

        • display:noneなら、子孫のbounding rectの計算や描画を行わない
      • 実際そういうアルゴリズムなのかは知りません

英語

  • place A squarely B

    • AをまっすぐBに向かわせる

      • Bは副詞句 (in the mediator)
      • オブジェクトの連絡の責務を全部Mediatorに押し付ける文脈で使用
  • adverse

    • 不利な
  • nominally

    • 名目上は

      • 実際には抜け道がある感じ?
      • subclassingをtemplateで回避できるよ、という文脈で使用