9

Factory Method パターン(Factory または Abstract Factory パターンと混同しないでください) は、Open/Closed の原則に違反していますか?

更新: 明確にするために、具象クラスに静的ファクトリ メソッドがあるシナリオについて言及しています。例 (これは FMP のウィキペディアのページからのものです):

class Complex 
{
    public static Complex fromCartesian(double real, double imag) {
        return new Complex(real, imag);
    }

    public static Complex fromPolar(double modulus, double angle) {
        return new Complex(modulus * cos(angle), modulus * sin(angle));
    }

    private Complex(double a, double b) {
       //...
    }
}

プライベート コンストラクターは、クラスのサブクラス化、つまり拡張を妨げていませんか?

新しいファクトリ メソッドをサポートするためにクラスを変更する必要はありませんか? たとえば、クラスが最初に fromCartesian しかなく、後で fromPolar が必要になった場合、これをサポートするためにクラスを変更する必要はありませんでしたか?

これらは両方とも Open/Closed に違反していませんか?

4

3 に答える 3

5

いいえ、それはオープン/クローズの原則にまったく違反していません。

Open / Closedは、既存のコードを変更せずに、システムの動作を変更できることを意味します。コードを拡張してさまざまな方法で使用できますが、古いコードはそのままで、再テストする必要はありません。

ファクトリメソッドパターンは、指定されたパラメータに基づいて異なるタイプのオブジェクトを作成します。ファクトリメソッドは、正しく実行されれば、実際にはオープン/クローズの原則でうまく機能します。ただし、新しいクラスを作成してから、ファクトリメソッドでそのタイプの新しいオブジェクトを作成する場合は、ファクトリメソッドを変更する必要があります。

ただし、ファクトリメソッドによって読み込まれるある種の構成ファイルまたはそのようなものがある場合は、ファクトリメソッドを変更する必要はありません...ファクトリメソッドによって作成されるオブジェクトを指示する構成ファイルだけです。ファクトリメソッド。

于 2010-03-04T17:11:35.993 に答える
4

Factory パターンは本質的にOCPの違反者ではありません。

それは、その後の行動をどのようComplexに受け止めるかによって異なります。

Complex新しいタイプのオブジェクトの生成をサポートする必要があり、それらをサポートするために新しいメソッドを追加しComplexて変更することを選択した場合、変更のために再度開く必要があるため、 OCPの違反者になることを意味します。ComplexfromXComplexComplex

class Complex 
{
    public static Complex fromCartesian(double real, double imag) {
        return new Complex(real, imag);
    }

    public static Complex fromPolar(double modulus, double angle) {
        return new Complex(modulus * cos(angle), modulus * sin(angle));
    }

    //class opened for modification
    public static Complex fromOtherMeans(String x , String y) {
        return new Complex(x, y);
    }
}

この問題を何らかのテキスト ファイルまたはプロパティ ファイルに書き込んで、Java クラスを変更しなくても済むようにすることはできますが、ソリューションのこの領域に追加のロジックを順番に記述する必要がなくなるわけではありません。の新しいタイプをサポートしますComplex

設計での の使用Complex方法 (さまざまなタイプの違いは? どのように使用していますか?) に応じて、適切に適用できる代替オプションがいくつかあります。

そのようなOCPに適した代替手段の 1 つは、サブクラス化Complexして追加のファクトリ メソッドを提供することです。サブクラスは、 がどのようComplexに拡張されても変更されないかを示す最も単純な例です。

この場合の変更に代わるOCPに適した別の方法は、 Decorator パターンです。OCPは変更されていませんが、新しい機能でラップすることによって拡張されているため、OCP を尊重する新しいバリアントを作成する機能を使用して継続的に装飾します。ComplexComplexComplexComplex

3 番目の選択肢はComplex、その計算が構成によって提供されるように、 の構造を変更することです。これにより、 Strategy パターンを使用して のさまざまな動作を区別する機会が開かれますComplex

Factory パターンの利点は、コンテキスト コードがOCPを尊重するのに役立つことです。ファクトリ クラスでOCPの右側にとどまるために上記の手法のいずれかを採用するかもしれませんが、同僚はオブジェクト グラフを一目見て、単一のファクトリ上にオブジェクト グラフを配置することの賢明さに疑問を呈する可能性があります。 、それを単純化して 1 つの Factory に戻すと、最初の例に戻ります。

そのような場合、Factory パターンの実装を曲げてSOLID原則を尊重しようとするのではなく、なぜそれを使用しているのかを考えてください

于 2014-06-24T09:03:43.177 に答える
2

いいえ。ウィキペディアのリンクから:

ソフトウェアエンティティ(クラス、モジュール、関数など)は、拡張のために開いている必要がありますが、変更のために閉じている必要があります

ファクトリメソッドのオーバーライドは拡張です。新しいクラスを作成しています。既存のクラスは変更しません。元のサブクラスを(できればIoCコンテナーの構成を介して)置き換える必要があります。

于 2010-03-04T17:10:34.000 に答える