私はTDDプロジェクトに参加しているので、そのような開発に関わる優れた評価にできるだけこだわるようにしています。それらの1つは、可能な限り静的およびグローバルを回避することです。
私はこの問題に直面しています。「オプション」(追加の「マイクロ記事」)をリンクできるオブジェクト「記事」があります。
私は基本的にオブジェクトごとに1つのクエリを作成する必要があるほどすべてが分離されている状況にあるため、逆効果にならない、またはクエリが多すぎない適切な方法を理解できません。
私の実際の観点から、私は3つのオプションを見ます:
1)記事の内部を作成します。
class Article
{
//[...]
public function getArrOption(){
//Build an array of Options instance.
//return an array of Options.
}
}
Pro:単純明快
Const:保守性:アーティクルオブジェクトにOptionオブジェクトの構築ロジックが含まれるようになりました。これはおそらくコードの重複につながります。
2)optionFactoryの使用
class Article
{
//[...]
public function getArrOption(){
return OptionFactory::buildFromArticleId($this->getId());
}
}
Pro:構築ロジックはArticleクラスの外にありません
Const:「静的はモックするのが難しい」ルールを破って、Articleクラスをテストするのを難しくしています。
3)すべてのロジックを分離します。
//Build the array of Option instance in a controller somewhere, using a Factory:
$arrOption = OptionFactory::buildFromArticleId($article->getId());
Pro:記事は彼自身の責任のみを処理し、オプションへの彼の「父親」リンクを気にしません。物事は本当に切り離されています
Const:オプションにアクセスする必要があるたびに、コントローラー内にさらにコードが必要になります。つまり、私はオブジェクト内でファクトリを決して使用しないでください。
行くための最良の方法は何ですか? (私は何かを見逃しましたか?)ありがとう。
編集:
言うまでもなく、クラス内でファクトリーを呼び出せない場合は、基本的に遅延初期化パターンも使用できません...
Staticは「悪い」ものではなく、モック不可能です。あざけることが意味をなさない場所でも使用できます。
これはFactoryパターンではなく、Repositoryパターンのように見えますが、そうではないかもしれません。ファクトリーは、同じインターフェース/基本クラスを持つ複数のクラスがあり、どのクラスを返すかを決定するロジックを分離したい場所です。リポジトリはリポジトリからデータを取得し、そのリポジトリの実装を抽象化します(記事は、そのオプションが同じDB、別のDB、XMLファイル、CSVファイルなどに保存されているかどうかを知る必要はありません)。
BuildFromArticleメソッドを呼び出すことができるコンストラクターで、ArticleクラスにObjectFactory(またはリポジトリなど)オブジェクトを与える可能性を無視しました。
私のPHPはさびていますが、次のように見えると思います:
class Article
{
private $_option_repository;
public function __construct($option_repository) {
$_option_repository = $option_repository;
}
//[...]
public function getArrOption(){
return $_option_repository->buildFromArticleId($this->getId());
}
}
これはあなたの上記の長所をすべて満たしていると思います。
静的メソッドは絶対に必要ではないと主張し、抽象ファクトリーは混乱を招くことが実証されており、解決策としての依存関係注入に向けた言語のわずかな変更を示唆しているという論文からの引用です。
インスタンスとそれらのクラスの間の密結合はカプセル化を破壊し、静的メソッドのグローバルな可視性とともに、テストを複雑にします。依存性注入をプログラミング言語の機能にすることで、静的メソッドを完全に取り除くことができます。以下のセマンティックの変更を採用しています。
(1)グローバルのすべての出現をインスタンス変数へのアクセスに置き換えます。
(2)そのインスタンス変数がインスタンス化されるときに、オブジェクトに自動的に注入されるようにします。