プログラム全体とテスト画像をドキュメントに含めて、テストを実行できます。
ファイル:n459.com/file/25127180-478678004
以下は関係ありません。
- - - - - - - - - - - - - - - - - - - - - -境界線 - - - ----------------------------------------
1.概要
抽象的なファクトリパターンは、製品ファミリに統一された作成インターフェイスを提供します。この製品ファミリの特定のシリーズが必要な場合、対応するシリーズを抽象ファクトリから選択して、特定のファクトリカテゴリを作成できます。このタイプのデザインパターンは作成パターンであり、オブジェクトを作成するための最良の方法を提供します。
抽象ファクトリパターンでは、インターフェイスは、クラスを明示的に指定せずに、関連するオブジェクトのファクトリを作成する役割を果たします。生成された各ファクトリは、ファクトリパターンに従ってオブジェクトを提供できます。
関連用語:
製品階層:製品の継承構造は、クラスの継承に似ています。たとえば、ノートブックは抽象的なカテゴリであるため、Huaweiノートブック、Apple、Lenovoノートブックがそのサブカテゴリです。
製品ファミリ:同じ工場で製造され、異なる製品階層にある製品のグループを指します。たとえば、Huaweiノートブック、携帯電話、ルーターなどはすべてHuaweiによって製造されていますが、ノートブックのグレード構造は異なり、製品ファミリーを形成しています。
抽象ファクトリ:複数の製品階層構造の宣言を含む、抽象ファクトリパターンのコアであるインターフェイスです。すべてのファクトリクラスは、このインターフェイスを実装する必要があります。
具体的なファクトリ:製品ファミリ内の製品オブジェクトのインスタンス化を担当するのは、抽象ファクトリの実現です。たとえば、Huaweiの工場では、Huaweiのノートブック、携帯電話、ルーターなどを製造しています。
2.製品ファミリーと製品レベルの構造図
1つのブランドを製品ファミリー、コンピューター、携帯電話、ルーターを製品レベルとします。各ブランドには独自の製品ファミリーがあり、完全な製品グループを構成します。
横は家族、縦はレベル、横と縦の交点は特定のブランドの特定の製品を表します(たとえば、下の図の交点はコンピューターです)。下の図を参照してください。
第三に、UML図
このクラス図は実際には比較的単純で、簡単な説明です。
製品のトップレベルインターフェイス:主に製品抽象クラスによって実装されます。
製品抽象クラス:特定の製品によって実現されるクラス。
特定の実装カテゴリ:抽象クラスAbstractRouterからのHuaweiルーター実装などの特定の製品実装。
工場インターフェース:各製品の作成方法は、工場インターフェースで定義されています。
特定のHuaweiファクトリー:ファクトリーインターフェイスを実装し、Huaweiファミリーの製品(ルーター、携帯電話、コンピューター)を作成します。
第4に、特定のコードの実装
コードでは、Huawei製品を例として取り上げ、Huaweiコンピューター、携帯電話、ルーター製品をそれぞれ定義します。UMLクラス図から、製品構造が比較的明確であることがわかります。次に、最初に製品を設計します。
以下の製品の定義を開始します。
トップ製品インターフェース;
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- 製品インターフェースを定義する
- @author ningbeibei
* /
public interface InterfaceProduct { void get(); }コピーコード コンピューター抽象クラスを定義し、製品のInterfaceProductインターフェイスを実装します。
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- コンピュータ製品の抽象クラスを定義し、製品インターフェイスInterfaceProductを実装します
- @author ningbeibei
* /
public abstract classAbstractComputersはInterfaceProductを実装します{ publicabstract void get(); }コード をコピーします携帯電話の抽象クラスを定義し、製品のInterfaceProductインターフェイスを実装します。
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- 携帯電話の抽象クラスを定義し、製品インターフェイスInterfaceProductを実装します
- @author ningbeibei
* /
public abstract classAbstractPhoneはInterfaceProductを実装します{ publicabstract void get(); }コード をコピーしますルーター抽象クラスを定義し、製品InterfaceProductインターフェイスを実装します。
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- ルーター製品の抽象クラスを定義し、InterfaceProductインターフェイスを実装します
- @author ningbeibei
* /
public abstract class AbstractRouterimplements InterfaceProduct { public abstract void get(); }コピーコード Huaweiコンピューターの具体的な実装クラスを定義し、AbstractComputers抽象クラスを継承します。
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- Huaweiコンピューター実装クラス
- @author ningbeibei
* /
public class HuaWeiComputer extends AbstractComputers { @Override public void get(){ System.out.println( "Huawei Notebook"); } }コピーコード Huawei携帯電話の具体的な実装クラスを定義し、AbstractPhone抽象クラスを継承します。
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- Huawei携帯電話実装クラス、
- @author ningbeibei
* /
public class HuaWeiPhone extends AbstractPhone { @Override public void get(){ System.out.println( "Huawei mobile phone"); } }コピーコード Huaweiルーターの具体的な実装クラスを定義し、AbstractRouter抽象クラスを継承します。
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- Huaweiルーター
- @author ningbeibei
* /
public class HuaWeiRouter extends AbstractRouter { @Override public void get(){ System.out.println( "Huawei brand router"); } }コピーコード ファクトリは以下で定義されます。
ファクトリインターフェイスを定義します。
コードをコピーします
Packagepattern.abstractfactory.factory;
Import pattern.abstractfactory.product.InterfaceProduct;
/ **
- 製品ファクトリインターフェイスを定義し、
- ningbeibei @author
* /
public interface InterfactFactory { //電話InterfaceProductcreatePhone(); //コンピューター製品InterfaceProductcreateComputer(); //ルーターInterfaceProductcreateRouter(); } インターフェイスInterfactFactoryを実装するコード具体的なファクトリ実装クラスをコピーします。
复制代码
パッケージpattern.abstractfactory.factory;
インポートpattern.abstractfactory.product.HuaWeiComputer;
インポートpattern.abstractfactory.product.HuaWeiPhone;
インポートpattern.abstractfactory.product.HuaWeiRouter;
インポートpattern.abstractfactory.product.InterfaceProduct;
/ **
- Huawei工場
- @author ningbeibei
/
public classHuaWeiFactoryはInterfactFactoryを実装します{ /
*- コンピューターオブジェクトを作成し、return
/
@Override
public InterfaceProduct createComputer(){ return new HuaWeiComputer(); } /
* - 携帯電話オブジェクトを作成し、return
/
@Override
public InterfaceProduct createPhone(){ return new HuaWeiPhone(); } /
* - ルーターオブジェクトを作成して返す
* /
@Override
public InterfaceProduct createRouter(){ return new HuaWeiRouter(); } }コピーコード テストクラス;
- コンピューターオブジェクトを作成し、return
复制代码
パッケージpattern.abstractfactory;
インポートpattern.abstractfactory.factory.HuaWeiFactory;
インポートpattern.abstractfactory.factory.InterfactFactory;
インポートpattern.abstractfactory.product.InterfaceProduct;
/ **
- 抽象ファクトリーパターンテストクラス
- @author ningbeibei
* /
public class test { public static void main(String [] args){ // Huaweiブランドファクトリを作成するInterfactFactoryhuawei = new HuaWeiFactory(); // Huaweiファクトリを介してHuaweiコンピュータオブジェクトを取得するInterfaceProductcomputer = huawei.createComputer( ); computer.get(); // HuaweiファクトリInterfaceProductを介してHuawei携帯電話オブジェクトを取得しますphone = huawei.createPhone(); phone.get(); // HuaweiファクトリInterfaceProductを介してHuaweiルータオブジェクトを取得しますrouter = huawei.createRouter(); router.get(); } }コピーコード 実行結果;
5.抽象ファクトリメソッドモデルが製品ファミリを拡張する方法
抽象ファクトリモデルは、水平方向の拡張には便利で、垂直方向の拡張には非常に困難です。つまり、Xiaomiブランドの拡張など、新しいブランドを拡張する場合、Xiaomi製品にはコンピュータ、携帯電話、ルーターの場合、新ブランドの展開は横展開で便利ですが、Xiaomiに炊飯器製品を追加するのは非常に難しいので縦展開なので、抽象的なファクトリーモデルを使用する場合は、適切なシーン、つまり異なるシーンを選択する必要があります。最適なパターンを使用することは、デザインパターンの本質です。
次に、新ブランドの製品ファミリーを水平方向に拡大してみましょう。特定のタイプのコンピューター、携帯電話、ルーター(Xiaomiブランド)を次のコードで追加する必要があります。
Xiaomi Computer
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- AbstractComputers抽象クラスから継承されたMiコンピューター
- @author ningbeibei
* /
public class MiComputer extends AbstractComputers { @Override public void get(){ System.out.println( "Millet Computer"); } }コピーコード Xiaomi Mobile
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- AbstractPhone抽象クラスから継承されたMi携帯電話
- @author ningbeibei
* /
public class MiPhone extends AbstractPhone { @Override public void get(){ System.out.println( "Mi mobile phone"); } }コピーコード Miルーター
コード
パッケージpattern.abstractfactory.product;
/ **をコピーします
- AbstractRouter抽象クラスから継承されたMiルーター
- @author ningbeibei
* /
public class MiRouter extends AbstractRouter { @Override public void get(){ System.out.println( "Millet router"); } }コピーコード 特定のミレットファクトリクラスを追加します
复制代码
パッケージpattern.abstractfactory.factory;
インポートpattern.abstractfactory.product.InterfaceProduct;
インポートpattern.abstractfactory.product.MiComputer;
インポートpattern.abstractfactory.product.MiPhone;
インポートpattern.abstractfactory.product.MiRouter;
/ **
- InterfactFactoryインターフェースを実装するMiFactory
- @author ningbeibei
* /
public classMiFactoryはInterfactFactoryを実装します{ // Xiaomi携帯電話@Overridepublic InterfaceProduct createPhone(){ return new MiPhone(); } // Xiaomiコンピューター@Overridepublic InterfaceProduct createComputer(){ return new MiComputer(); } / / Xiaomi router @Override public InterfaceProduct createRouter(){ return new MiRouter(); } }コードをコピーする 最後にテストカテゴリを記述します。コードの赤いフォントは新しく拡張されたブランド製品です。
复制代码
パッケージpattern.abstractfactory;
インポートpattern.abstractfactory.factory.HuaWeiFactory;
インポートpattern.abstractfactory.factory.InterfactFactory;
インポートpattern.abstractfactory.factory.MiFactory;
インポートpattern.abstractfactory.product.InterfaceProduct;
/ **
-
抽象ファクトリーパターンテストクラス
-
@author ningbeibei
* /
public class test { public static void main(String [] args){ // Huaweiブランドファクトリを作成しますInterfactFactoryhuawei = new HuaWeiFactory(); // Huaweiファクトリを介してHuaweiコンピュータオブジェクトを取得しますInterfaceProductcomputer = huawei.createComputer( ); computer.get(); // Huaweiファクトリーphone = huawei.createPhone(); phone.get();を介してHuawei携帯電話オブジェクトInterfaceProductを取得します。//HuaweiルーターオブジェクトInterfaceProduct router = huawei.createRouter();を取得します。router.get();
// 创建小米品牌工厂 InterfactFactory Mifactory = new MiFactory(); // 通过小米工厂获取小米电脑对象 InterfaceProduct micomputer = Mifactory.createComputer(); micomputer.get(); // 通过小米工厂获取小米手机对象 InterfaceProduct miphone = Mifactory.createPhone(); miphone.get(); // 通过小米工厂获取小米路由器对象 InterfaceProduct mirouter = Mifactory.createRouter(); mirouter.get();
}
}
コピーコード
実行結果:
注:上記のブランド拡張により、水平方向の拡張は簡単で、垂直方向の拡張は非常に難しいことがわかりました。コードはブランドの既存の製品を簡単に拡張できますが、Huaweiタブレットの拡張など、未定義の製品を拡張することは非常に困難です。 、ファクトリロジックコードを変更し、新しい製品構造を追加する必要があります。これは明らかにデザインモードの開閉の原則に準拠していないため、使用する際には明確に検討し、新しい製品レベルの拡張がないことを確認する必要があります。
第六に、長所と短所および使用シナリオの
長所
抽象ファクトリパターンは、具体的なクラスの生成を分離するため、顧客は何が作成されているかを知る必要がありません。この分離により、コンクリート工場の交換は比較的容易であり、すべてのコンクリート工場は抽象工場で定義されたパブリックインターフェースを実装しているため、コンクリート工場のインスタンスを変更するだけで、ソフトウェア全体をある程度変更できます。システムの動作。
ファミリ内の複数のオブジェクトが連携して動作するように設計されている場合、クライアントが常に同じファミリ内のオブジェクトのみを使用するようにすることができます。
「開閉原理」に沿って、既存のシステムを変更する必要がなく、新しいファミリを追加すると非常に便利です。
不利益
新しい階層構造を追加するのは面倒で、元のシステムに大幅な変更を加える必要があり、抽象レイヤーコードを変更する必要さえあります。これは明らかに大きな不便をもたらし、「開閉の原則」に違反します。
使用するシーン
システムは、特定のクラスインスタンスの作成、結合、および表現の詳細に依存するべきではありません。これは、すべてのタイプのファクトリパターンにとって重要です。ユーザーは、オブジェクトの作成プロセスを気にしたり、オブジェクトの作成と使用を切り離したりする必要はありません。
システムには複数のファミリがあり、一度に1つだけが使用されます。ユーザーは、構成ファイルやその他の方法でファミリーを動的に変更でき、新しいファミリーを簡単に追加することもできます。
階層構造は安定しています。設計が完了した後、新しい階層構造がシステムに追加されたり、既存の階層構造が削除されたりすることはありません。
セブン、
文章の不備を批判して訂正したいのですが、コメント欄に不備を指摘して、時間の間違いを訂正し、読者の誤解を避けるようにお願いします。もっとご意見をいただければ幸いです。