「4つのギャング」デザインパターンから、ファクトリメソッドがあります。
class Factory(product)
case product
when a
new A
when b
new B
when c
new C
end
new Factory(a)
なぜこれが、3つのクラスが持つよりも有用であるa
、b
とc
し、それらを個別に呼び出しますか?
「4つのギャング」デザインパターンから、ファクトリメソッドがあります。
class Factory(product)
case product
when a
new A
when b
new B
when c
new C
end
new Factory(a)
なぜこれが、3つのクラスが持つよりも有用であるa
、b
とc
し、それらを個別に呼び出しますか?
回答:
あなたの例は十分に複雑ではないからです。このような単純なシナリオでは、高度なパターンを使用することも意味がありません。
しかし、A、B、またはCを構築するために製品以上のことを知る必要があり、その知識に直接アクセスできない場合、それは役に立ちます。次に、ファクトリを使用して、必要なオブジェクトを生成するためのナレッジセンターとして機能します。
これらのオブジェクトには、ファクトリが提供できるオブジェクトXへの参照が必要な場合がありますが、A、B、またはCを構築する場所のコードは、Xにアクセスできないか、アクセスするべきではありません。 AとBを作成しますが、Yタイプがある場合はCを作成します。
また、作成するのに20個の依存関係が必要なオブジェクトがあることも考慮してください。それで何?アクセスできないはずの場所でそれらの依存関係を探しに行くのは問題があるかもしれません。
Factory Methodパターンは、呼び出し側クラスから意思決定プロセスを抽象化します。これにはいくつかの利点があります。
再利用。多くの場所でインスタンス化する場合、条件を繰り返す必要はありません。そのため、新しいクラスを追加するときに、クラスが欠落するリスクはありません。
ユニットテスタビリティ。ファクトリーに対して3つのテストを作成し、正しい条件で正しい型を返すことを確認し、呼び出し元のクラスをテストするだけで、ファクトリーを呼び出してから、返されたクラスで必要なメソッドを呼び出すことができます。ファクトリ自体または具象クラスの実装について何も知る必要はありません。
拡張性。誰かがこのファクトリに新しいクラスDを追加する必要があると判断した場合、呼び出しコード、ユニットテスト、実装のいずれも通知する必要はありません。新しいクラスDを作成し、ファクトリメソッドを拡張するだけです。これは、Open-Closed Principleのまさに定義です。
テスト中にクラスDのオンとオフを切り替えたい場合など、状況に応じて、新しいファクトリクラスを作成し、ホットスワップ可能にすることもできます。この状況に遭遇したのは一度だけですが、非常に役に立ちました。
既に述べたように、ファクトリーパターンは必ずしも進むべき道ではありません。ただし、条件付きインスタンス化が表示される場合はいつでも、少し考えてみてください。
Factoryパターンの主な利点は2つあります。
製品の実装が必要な場所は、製品の構築方法を知る必要はありません。工場はその情報を保持しています。
特定のコンストラクターに渡す引数を知りたいですか?または、どの依存関係を注入する必要がありますか?または、完全に構成された後に実装クラスをデータベースに登録する方法は?いや?工場にすべてのことを見てもらいましょう。
製品の実装を必要とする場所は、モジュールの記述時(つまり、コンパイル時)に実装クラスの名前を知る必要はありません。
したがって、a
何もする必要はありませんA
。「構築するもの」は、名前だけでなく、目的の非機能プロパティの観点から説明できます。これははるかに柔軟です。
欠点は、何をどのように作成するかを知っていると、ファクトリーを使用するときに複雑さが増すことです。ただし、それに対する修正は簡単です。意味をなさない場合はファクトリを使用しないでください。
クラスが「人」であるという観点から、デザインパターンについて考えたいと思います。パターンは、人々が互いに話す方法です。
ですから、私にとって、工場のパターンは雇用機関のようなものです。可変数のワーカーが必要な人がいます。この人は、雇う人に必要な情報を知っているかもしれませんが、それだけです。
そのため、新しい従業員が必要になったとき、雇用代理店に電話して必要なものを伝えます。さて、実際に誰かを雇うには、多くのことを知っておく必要があります-福利厚生、資格の確認など。しかし、雇用する人はこれを知る必要はありません。
同様に、ファクトリを使用すると、コンシューマは作成方法や依存関係の詳細を知る必要なく、新しいオブジェクトを作成できます。実際に必要な情報を提供するだけです。
Factoryパターンは、最も頻繁に使用され、乱用されたデザインパターンです。
単純なコンストラクターで十分な場合にFactoryクラスがコーディングされるという多くのケースに遭遇しました。
次の場合を除き、ファクトリクラスを使用しないでください。
サブクラスをインスタンス化するときにファクトリメソッドを使用します。クライアントコードは、どの特定のサブクラスをインスタンス化するかを決定する責任を負っていません。
インスタンス化するクラスを変更する必要があるときにクライアントコードを変更する必要がないため、便利です。既存のコードを変更することは、通常エラーが発生しやすいため、悪い習慣です。
例としては、サブクラスがあり、各サブクラスはデータを昇順で並べ替えますが、方法は異なります。それぞれの方法は、特定の種類のデータに最適です。例:部分的にソートされたデータ、数字などのデータ。クライアントコードは、データの印刷のみを処理するクラスです。どのソートクラスをクライアントクラスでインスタンス化するかを決定するコードがあると、複雑なクラスになります。言い換えると、この場合、複数の責任を持つことは、どのソートクラスが最適であるかを決定し、データを印刷します。どのソートクラスをインスタンス化するかを決定するコードをFactoryクラスに入れることにより、懸念を分離し、どのソートサブクラスがインスタンス化されるかを変更する必要があるたびにクライアントクラスを変更する必要がなくなります。
クラスをインスタンス化する方法やクラスの自己決定的な変化を予測できる場合、それはあなたの腕をカバーする方法です。ファクトリクラスは使用する意味があります。これにより、クラスが1つの責任に集中できるようになり、その結果、関連していない既存のコードを変更する必要が少なくなります。