Dependency Injectionコンテナの導入によるドメインモデルの改善 : Symfony Advent Calender 2011 JP - 11日目
PHPメンターズの久保です。本記事はSymfony Advent Calendar JP 2011の11日目の記事となります。
私は現在Piece Frameworkの新プロダクトとして継続的テスティングプラットフォームMakeGood Universeの開発を進めていますが、並行してMakeGood Universe(およびMakeGood)のテストランナーフレームワーク部分を担当するStagehand_TestRunnerのバージョン3の開発も進めています。
Stagehand_TestRunner 3の開発においては各機能の実装にSymfonyのコンポーネントを全面採用することにしており、DependencyInjectionコンポーネントの導入もその一環です。DependencyInjectionコンポーネントを導入する最大の動機は、Configコンポーネントとの合わせ技によるYAMLベースの設定ファイルの実現にあります。

YAMLベースの設定ファイルは問題空間の言語で書かれており、変換器を通して解決空間の言語で書かれたDIコンテナの定義に変換されます。コマンドラインも問題空間の言語であり、同じ仕組みの中に統合されます。
さて、大規模な構造改善に着手したのもつかの間、問題があることがわかりました。これまでのStagehand_TestRunnerでは、事実上グローバルなConfigオブジェクトを各コンポーネントが参照することによってアプリケーションの設定にアクセスしていました。

この設計にはドメインモデルの欠落(あるいはコードへの未反映), 関連性のない情報への参照の発生といった問題があります。そこで最初のステップとして、グローバルなConfigオブジェクトに設定していたパラメータを各コンポーネントに直接設定する形への移行に取り組みました。

しかし、この設計には同じパラメータが異なるサービスの引数に繰り返し設定されるという問題があります。グローバルなConfigオブジェクトとは異なり、サービスに設定されるパラメータはリテラルなので、同一パラメータの値が設定されるタイミングによって異なるといった問題も発生するでしょう。
Configオブジェクトの廃止と、DIコンテナのパラメータとサービスの引数への設定に移行したことにより、関連性のない情報への参照は発生しなくなりましたが、ドメインモデルの不在はより顕在化しました。そこで次のステップとして、各パラメータの適切な配置先となるオブジェクトを用意し、パラメータからオブジェクトへの変換は1度のみ行うことにしました。もちろん、適切な配置先となるオブジェクトは単に用意するという性格のものではなく、ドメインモデルが反映されているものでなければなりません。

Dependency Injectionコンテナの導入により必ずしも設計やドメインモデルの改善ができるとは限りませんが、ドメインモデルの欠落やコードへの未反映を発見する契機とすることはできるでしょう。
Symfony Advent Calendar JP 2011 12日目となる明日の担当は、Silex使いの@77webさんです。