特徴 | 詳細 | 関連する概念 |
処理の部品化 | 処理を Expression 役インタフェースの実装として部品化することにより、部品の組み合わせによる再利用を容易にする。 | Strategy |
処理の共通化 | 共通の処理を委譲元で定義し個別の処理を委譲先に委譲することにより、個別の処理に依存することなく共通の処理を部品化することができる。 | Delegation, Template Method |
処理の構造化/組み立て/宣言 | 処理部品を組み立てて構造的にオブジェクト指向のデータ構造として宣言することにより、プログラムを大局的にとらえることができる。 | Composite, 構造化プログラミング |
処理間の依存性の分離 | インタープリタパターンを使用することにより構造化されたプログラムから各構造間の依存性を分離することが可能である。 | 委譲、LISPマクロ |
処理の選択 | 処理を構造化する際に結合する処理部品をユーザに選択させることにより、ユーザに対しプログラムを大局的にとらえさせることができる。(処理のDI) | Strategy, DI / IoC |
処理の分岐 | 状態により委譲先を分岐する処理部品を定義することが可能。 | フィルタ |
処理の省略 | 状態により委譲先への委譲をスキップする処理部品を定義することが可能。 | Balking |
処理の代理 | 委譲先の処理を代理する処理部品を定義することが可能。 | Proxy |
オブジェクトの共有 | 委譲先で生成したオブジェクトを保持し、次のアクセスに対して保持したオブジェクトを再利用する処理部品を定義することが可能。 | Flyweight |
処理の追加と制限 | 委譲先の処理の前後に処理を追加したり処理を制限したりする処理部品を定義することが可能。 | Decorator |
横断的な処理の定義 | 業務をまたがった横断的な処理部品を定義することが可能。 | AOP |
資源の生成から破棄までの部品化 | 委譲先で使用する資源の生成と破棄を管理する処理部品を定義することが可能。 | Before After |
処理部品間の連携 | 複数の処理部品の間に同一パラメータなどのコンテキストがある場合、それらの処理部品を生成するためのクラスを定義することが可能。 | Hook Operation |
スレッド別のデータ保持 | ThreadLocal を使用することにより 処理部品の不変性を維持しつつスレッド別でデータを扱うことが可能。 | Thread - Specific Storage |
複雑な処理の隠蔽 | 処理部品の中で処理部品を構造的に宣言したり、処理部品を生成する静的メソッドを定義することにより構造を隠蔽することが可能。 | Facade, LISPマクロ |
コンテキストの分離 |
Expression 役と Context 役を分離することによりデータの管理を容易にする。
ロック/セマフォなどの継続的な状態や固定値などの揮発性のないデータは Expression 役で定義するのが適している。
リクエスト処理終了後に破棄される揮発性のあるデータや業務モデルなどバインドされる必要のあるデータは Context 役で管理するのが適している
(インタープリタパターンの特徴:副作用に対する戦略参照)。
インタープリタパターンにおける Expression 役と Context との関係は、C言語における関数と構造体の関係と相似なので、
オブジェクト指向を習い始めのころはインタープリタパターンが「オブジェクト指向的でない」と感じられる方もいるかもしれない。
| 構造体 (C言語) |
処理枠組の選択 | Visitor パターンを適用することにより、処理部品の動作定義とは別に、コンストラクタツリーをデータとみなして操作を定義することが可能。 | Visitor, Annotation, Double Dispatch |
揮発性のないデータの注入 | 揮発性のないデータを処理部品で使用する場合、処理部品内でデータを取得する代わりにコンストラクタ引数で注入することにより、再利用性を維持することが可能。(データ(揮発性のないデータ)のDI) | DI / IoC |
例外処理の構造化 |
コンストラクタツリーのある箇所で例外が発生した場合、
Java言語の機構によりその例外の処理を行うことが可能なノードに到達するまで木構造の葉から根に向かって処理が委譲される自然な構造を持つ。
| Chain of Responsibility |
Web アプリケーションへの適用容易性 |
Web アプリケーションはアップストリームとダウンストリームがベースなので、
処理の流れを構造化し横断化することが容易なインタープリタパターンを適用するのが適している。
| 調査中 |
以上の表より、インタープリタ デザインパターンはその他の多くのデザインパターンと関連していることがわかる。
注意点と考慮点 | 詳細 | 関連する概念 |
高凝集度 | 再利用性を維持するために処理の凝集度が高くなる単位で処理部品を定義する必要がある。 | High Cohesion (GRASP) |
疎結合度 | 再利用性を維持するために処理の結合度が疎になる単位で処理部品を定義する必要がある。 | Low Coupling (GRASP) |
インスタンスの不変性の維持 | 処理部品で扱うデータが参照型で可変の場合、処理部品インスタンスの不変性を維持するためにオブジェクトのコピーをとる必要がある。 | Immutable |
処理を行わない部品 | 処理を行わない処理部品を定義することによりフレームワーク全体が複雑化することを抑止することが可能。 | Null Object |
目的別部品群の定義と部品群間の接続 | 目的別に処理部品の Expression 役インタフェースを宣言することによりラベリングによるアイデア創発を促進する。複数の処理部品群を接続するために Adapter パターンを適用する。 | Adapter |
揮発性のあるリソースの生成 | 処理部品の不変性を維持するため、揮発性のあるリソースを生成するファクトリは複数のスレッドで同時に使用可能である必要がある。(リソース(揮発性のあるデータ)のDI) | 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 の横断化・一部ファイル化など設定の柔軟性を維持したり、処理と設定の混同を防止したりすることが可能。さらに静的型定義言語の場合は早期にエラーを検出することが可能。 | 調査中 |
実行/分岐ステップ数(カバレージ)の評価 | コンストラクタツリー宣言は実行されたステップとしてカウントされるため、見かけ上カバレージが多いように見える。カバレージによる品質評価を行う際は注意する必要がある。各々のコンストラクタツリーの実行状況を測定する方法を調査している。 | 調査中 |
パターン | クラス |
Strategy
|
../doc/woolpack/dom/DelegateDomExpression.html
../doc/woolpack/dom/Evaluable.html
../doc/woolpack/validator/ValidatorIterable.html
|
Template Method
|
../doc/woolpack/config/CacheMap.html
../doc/woolpack/config/PutResourceBundle.html
../doc/woolpack/container/AbstractComponentDef.html
../doc/woolpack/dom/CacheNode.html
../doc/woolpack/el/AbstractToELTargetExceptionEL.html
../doc/woolpack/html/AbstractCountProperty.html
../doc/woolpack/utils/concurrent/DoSemaphore.html
|
Balking
|
../doc/woolpack/dom/DoAcquire.html
../doc/woolpack/dom/DoAcquireSession.html
../doc/woolpack/dom/JoinProcess.html
../doc/woolpack/ee/DoAcquireTransaction.html
../doc/woolpack/el/MapPropertyELFactory.html
|
フィルタ
|
../doc/woolpack/dom/Branch.html
../doc/woolpack/dom/BranchButton.html
../doc/woolpack/dom/BranchByAttrValue.html
../doc/woolpack/dom/If.html
../doc/woolpack/dom/XPath.html
../doc/woolpack/html/BranchPropertyCount.html
../doc/woolpack/locale/BranchByLocale.html
../doc/woolpack/locale/BranchByLocaleValidator.html
../doc/woolpack/locale/LocaleFormatFactory.html
../doc/woolpack/locale/LocaleReaderFactory.html
../doc/woolpack/utils/BranchInputStreamFactory.html
../doc/woolpack/validator/AbstractBranchValidator.html
../doc/woolpack/validator/BranchByIdValidator.html
../doc/woolpack/validator/BranchByNameIfExistsValidator.html
../doc/woolpack/validator/BranchByNameValidator.html
../doc/woolpack/validator/IfNotValidator.html
../doc/woolpack/validator/IfValidator.html
|
Proxy
|
../doc/woolpack/config/CacheMap.html
../doc/woolpack/config/ConfigCount.html
../doc/woolpack/config/CopyConfigContext.html
../doc/woolpack/crud/MarkedStringBuilder.html
../doc/woolpack/crud/QueryFactoryCacheImpl.html
../doc/woolpack/crud/UpdatableFactoryCacheImpl.html
../doc/woolpack/dom/CacheNode.html
../doc/woolpack/dom/Count.html
../doc/woolpack/dom/DoAcquire.html
../doc/woolpack/dom/DoAcquireSession.html
../doc/woolpack/dom/DumpIfCatch.html
../doc/woolpack/dom/InsertElementToChild.html
../doc/woolpack/dom/InsertElementToParent.html
../doc/woolpack/dom/JoinProcess.html
../doc/woolpack/dom/Loop.html
../doc/woolpack/dom/MeasureLapTime.html
../doc/woolpack/dom/SaveInputForBack.html
../doc/woolpack/dom/Sleep.html
../doc/woolpack/dom/XPath.html
../doc/woolpack/ee/DoAcquireTransaction.html
../doc/woolpack/el/AbstractToELTargetExceptionEL.html
../doc/woolpack/el/CachePropertyELFactory.html
../doc/woolpack/el/convert/CollectionConverter.html
../doc/woolpack/html/FrameToTable.html
../doc/woolpack/locale/LocaleCacheMap.html
../doc/woolpack/locale/LocaleCacheNode.html
../doc/woolpack/locale/LocaleId.html
../doc/woolpack/text/TrysDateFormat.html
../doc/woolpack/utils/XmlTransformerFactorySemaphoreImpl.html
../doc/woolpack/validator/CountValidator.html
../doc/woolpack/validator/DumpValidator.html
../doc/woolpack/validator/ValueLoopValidator.html
|
Decorator
|
../doc/woolpack/action/NotForwardMatcher.html
../doc/woolpack/utils/NewStringKeyMap.html
../doc/woolpack/validator/NotValidator.html
|
Before After
|
../doc/woolpack/dom/DoAcquire.html
../doc/woolpack/dom/DoAcquireSession.html
../doc/woolpack/dom/JoinProcess.html
../doc/woolpack/ee/DoAcquireTransaction.html
|
Hook Operation
|
../doc/woolpack/ee/ActionBuilder.html
../doc/woolpack/ee/SessionClearBuilder.html
../doc/woolpack/ee/TransactionBuilder.html
../doc/woolpack/ee/ValidatorBuilder.html
../doc/woolpack/test/RunnableGate.html
|
Visitor
|
../doc/woolpack/visitor/Acceptable.html
../doc/woolpack/visitor/Visitor.html
|
Adapter
|
../doc/woolpack/adapter/ConvertableTypeConverter.html
../doc/woolpack/adapter/JXE.html
../doc/woolpack/adapter/JXP.html
../doc/woolpack/adapter/JXPFactory.html
../doc/woolpack/adapter/OGE.html
../doc/woolpack/adapter/OgnlCollectionTypeConverter.html
../doc/woolpack/adapter/ToNodeUsingNeko.html
../doc/woolpack/config/PutResourceBundle.html
../doc/woolpack/config/ResolveEmbedding.html
../doc/woolpack/container/ScopeContainer.html
../doc/woolpack/dom/DoEL.html
../doc/woolpack/dom/EvalEL.html
../doc/woolpack/ee/ActionBuilder.html
../doc/woolpack/ee/ConfigDomExpression.html
../doc/woolpack/ee/HttpSessionMap.html
../doc/woolpack/ee/ServletContextMap.html
../doc/woolpack/ee/ServletInputStreamFactory.html
../doc/woolpack/ee/ServletRequestAttributeMap.html
../doc/woolpack/ee/ValidatorBuilder.html
../doc/woolpack/el/convert/FormatConverter.html
../doc/woolpack/el/convert/ParseConverter.html
../doc/woolpack/el/convert/ValidatorConverter.html
../doc/woolpack/locale/LocalePutResourceBundle.html
../doc/woolpack/test/DomExpressionRunnable.html
../doc/woolpack/test/RunnableDomExpression.html
../doc/woolpack/utils/AppendableWriter.html
../doc/woolpack/utils/concurrent/DoLock.html
../doc/woolpack/utils/concurrent/DoSemaphore.html
../doc/woolpack/utils/concurrent/TryLock.html
../doc/woolpack/utils/concurrent/TrySemaphore.html
../doc/woolpack/utils/InputStreamReaderFactory.html
../doc/woolpack/utils/NodeFindableFactoryImpl.html
../doc/woolpack/utils/StringInputStreamFactory.html
../doc/woolpack/utils/StringReaderFactory.html
../doc/woolpack/utils/XmlTransformerFactoryImpl.html
../doc/woolpack/validator/FormatValidator.html
../doc/woolpack/validator/ParseValidator.html
|
Abstract Factory
|
../doc/woolpack/crud/ExpressionFactory.html
../doc/woolpack/crud/ExpressionFactory2.html
../doc/woolpack/crud/QueryFactory.html
../doc/woolpack/crud/UpdatableFactory.html
../doc/woolpack/text/FormatFactory.html
../doc/woolpack/utils/concurrent/AcquirableFactory.html
../doc/woolpack/utils/InputStreamFactory.html
../doc/woolpack/utils/NodeFindableFactory.html
../doc/woolpack/utils/ReaderFactory.html
../doc/woolpack/utils/XmlTransformerFactory.html
|
Prototype
|
../doc/woolpack/text/CloneFormatFactory.html
|