インタープリタ デザインパターンの特徴
  インタープリタ デザインパターンは、 Context 役のインスタンスに Expression 役の木構造の中をくぐらせて Context 役の内部状態を加工するためのパターンである。(図参照)。

  図:インタープリタ デザインパターンの構造

  インタープリタ デザインパターンの特徴を以下に示す。

  特徴 | 詳細 | 包含または関連する概念
  --- | --- | ---
  処理の部品化 | Expression 役のインタフェースを実装することにより処理を部品化する。 | Strategy
  処理の共通化 | 共通の処理を委譲元で定義し、個別の処理を委譲先に委譲する。 | Delegation, Template Method
  処理の構造化/組み立て/宣言 | 部品を組み立てることにより処理を構造的に宣言する。 | Composite
  処理の選択 | 処理を構造化する段階で結合する部品をユーザが選択する。 | Strategy, DI / IoC
  処理の分岐 | 状態により委譲先を分岐する部品を定義することが可能。 | フィルタ
  処理の省略 | 状態により委譲先への委譲をスキップする部品を定義することが可能。 | Balking
  処理の代理 | 委譲先の処理を代理する部品を定義することが可能。 | Proxy
  オブジェクトの共有 | 委譲先で生成したオブジェクトを保持し、次のアクセスに対して保持したオブジェクトを再利用する部品を定義することが可能。 | Flyweight
  処理の追加と制限 | 委譲先の処理の前後に処理を追加したり処理を制限したりする部品を定義することが可能。 | Decorator
  横断的な処理の定義 | 業務をまたがった横断的な部品を定義することが可能。 | AOP
  資源の生成から破棄までの部品化 | 委譲先で使用する資源の生成と破棄を管理する部品を定義することが可能。 | Before After
  処理部品間の連携 | 複数の処理部品の間に同一パラメータなどコンテキストがある場合、それらの部品を生成するためのクラスを定義することが可能。 | Hook Operation
  スレッド別のデータ保持 | ThreadLocal を使用することにより 部品の不変性を維持しつつスレッド別でデータを扱うことが可能。 | Thread - Specific Storage
  複雑な処理の隠蔽 | 部品の中で部品を構造的に宣言することにより構造を隠蔽することが可能。 | Facade
  コンテキストの分離 | Expression 役と Context 役を分離することによりデータの管理を容易にする。 ロック/セマフォなどの継続的な状態や固定値などの揮発性のないデータは Expression 役で定義するのが適している。 処理終了後に破棄されるリクエストなどの揮発性のあるデータや業務モデルなどバインドされる必要のあるデータは Context 役で管理するのが適している。 | 調査中

  以上の表より、インタープリタ デザインパターンはその他の多くのデザインパターンを包含し、また関連していることがわかる。
  インタープリタ デザインパターンを適用する際の注意点と考慮点を以下に示す。

  注意点と考慮点 | 詳細 | 関連する概念
  --- | --- | ---
  揮発性のないデータの注入 | 揮発性のないデータをを取得する場合、部品内で取得する処理を定義する代わりにコンストラクタ引数から取得することにより、再利用性を維持することが可能。 | DI / IoC
  高凝集度 | 再利用性を維持するために処理の凝集度が高くなる単位で部品を定義する必要がある。 | High Cohesion (GRASP)
  疎結合度 | 再利用性を維持するために処理の結合度が疎になる単位で部品を定義する必要がある。 | Low Coupling (GRASP)
  インスタンスの不変性の維持 | 部品で扱うデータが参照型で可変の場合、部品インスタンスの不変性を維持するためにオブジェクトのコピーをとる必要がある。 | Immutable
  処理を行わない部品 | 処理を行わない部品を定義することによりフレームワーク全体が複雑化することを抑止することが可能。 | Null Object
  目的別部品群の定義と部品群間の接続 | 目的別に Expression 役インタフェースを宣言することによりラベリングによるアイデア創発を促進する。複数の部品群を接続するために Adapter パターンを適用する。 | Adapter
  処理枠組の選択 | オブジェクト構造と別にユーザが操作を選択するために Visitor パターンを適用することが可能。 | Visitor, Annotation
  揮発性のあるリソースの生成 | 部品の不変性を維持するため、揮発性のあるリソースを生成するファクトリは複数のスレッドで同時に使用可能である必要がある。 | Abstract Factory, Factory Method, Prototype, Immutable
  部品の静的宣言 | Null Object など、業務としてのみでなくフレームワークとして一意な部品を静的変数として宣言することにより、設計の見える化を維持することが可能。 | Singleton
  参照キーのカプセル化 | 設計に参照キーが現れた場合はフレームワークの都合によるファンクションポイントが発生している可能性がある。 Thread Specific Strage や Interpreter の適用を検討することにより 参照キーによるバインド処理がカプセル化され、実装の見える化を維持することが可能。 (例：org.apache.struts.action.ActionMapping#findForward() や Struts-config.xml の form-bean/@name など) | データモデリング, ファンクションポイント法
  静的型定義/動的型定義の使い分け | フレームワークの設計にはラベリングによるアイデアの創発のため静的型定義を適用するのが有効である。 逆にフレームワークと個別業務を接続するためには静的型定義を適用せずに動的型定義のみを適用するのが有効である。 (静的型定義の有効性は Woolpack におけるサーバ側値検証とクライアント値検証の比較で確認した。 また動的型定義のみの有効性は Woolpack テストにおける ToELTargetExceptionEL インナークラスによる業務呼び出しとOGNLによる業務呼び出しの比較で確認した。) | KJ法(創発技法のひとつ)
  プラグインの構造化 | プラグインによるフレームワーク拡張機構が設計に表れた場合は、インタープリタ パターン適用を検討することにより拡張機構の構造化を発見することが可能。(メタファ:USBカスケード接続) | Strategy
  ファクトリの構造化 | ファクトリが設計に表れた場合は、インタープリタ パターンの適用を検討することによりオブジェクト生成の構造化を発見することが可能。(例:woolpack.utils.InputStreamFactory) | Abstract Factory
  Context 役で管理するプロパティの選定 | Context 役で管理するプロパティの選定は、汎用性を考慮する必要がある。(例:woolpack.dom.DomExpression から org.w3c.dom.Node 型のプロパティを排除することによりテンプレート技術に依存しない API にすることが可能であるが、DOM 加工を行う Expression 役との接続で特化メカニズムが使用可能か検討中。) | Generalization
  XML ファイルによる設定方式の代替 | XML ファイルによる設定が設計に表れた場合は インタープリタ パターン適用を検討することにより、分割・ DI の横断化・一部ファイル化など設定の柔軟性を維持したり、処理と設定の混同を防止したりすることが可能。さらに静的型定義言語の場合は早期にエラーを検出することが可能。 | 調査中
  実行/分岐ステップ数(カバレージ)の評価 | コンストラクタツリー宣言は実行されたステップとしてカウントされるため、見かけ上カバレージが多いように見える。カバレージによる品質評価を行う際は注意する必要がある。各々のコンストラクタツリーの実行状況を測定する方法を調査している。 | 調査中

  インタープリタ デザインパターンとその他のオブジェクト指向の用語との関係を以下に示す。

  用語 | 関係
  --- | ---
  Chain of Responsibility | チェイン オブ レスポンシビリティ デザインパターンが木構造の葉から根に向かって処理を委譲するのに対し、 インタープリタ デザインパターンは木構造の根から葉に向かって処理を委譲する。

トップに戻る
Copyright (C) 2006 Takahiro Nakamura. All rights reserved.