今日は、非常に頻繁に使用されるもう 1 つの抽象ファクトリ パターンを見ていき、原則を読んだ後、.NET と JAVA の実装ソース コードを示します。
意味:
Abstract Factory Pattern:特定のクラスを指定せずに、一連の関連オブジェクトまたは相互依存オブジェクトを作成するためのインターフェイスを提供します。
抽象ファクトリ パターン: 具体的なクラスを指定せずに、関連オブジェクトまたは依存オブジェクトのファミリーを作成するためのインターフェイスを提供します。
ツール(キット)モードとも呼ばれます
抽象ファクトリー パターンの具体的なファクトリーは、製品を作成するだけではなく、製品ファミリーの作成を担当します。
ファクトリ階層が、異なる製品階層に属する製品ファミリ内のすべてのオブジェクトを作成できる場合、抽象ファクトリ パターンはファクトリ メソッド パターンよりも単純で効率的です。
分析します:
特定の各ファクトリには、オーバーロードされたファクトリ メソッドが 1 つまたはセットのみあり、製品は 1 つしか生産できません。そのため、システム内に多数のファクトリ クラスが存在する可能性があり、必然的にシステムのオーバーヘッドが増加します。
工場は一連の製品 (製品ファミリー) を生産できるため、工場クラスの数が大幅に削減されます。
製品階層構造:製品階層構造は製品の継承構造です。
製品ファミリー:製品ファミリーとは、同じ工場で生産され、異なる製品階層構造に位置する製品のグループを指します。
クラス図:
抽象ファクトリ パターンには次の4 つの役割が含まれます。
AbstractFactory (抽象ファクトリー)
ConcreteFactory(コンクリート工場)
AbstractProduct (抽象プロダクト)
コンクリート製品(特定製品)
適用性:
システムは、製品クラスのインスタンスがどのように作成、構成、表現されるかという詳細に依存すべきではありません。
システムには複数の製品ファミリーがありますが、一度に使用されるのはそのうちの 1 つだけです
同じ製品ファミリーに属する製品は一緒に使用されるため、この制約をシステムの設計に反映する必要があります。
製品レベル構造は安定しています。設計の完了後、新しい製品レベル構造がシステムに追加されたり、既存の製品レベル構造が削除されたりすることはありません。
アドバンテージ:
クライアントが何が作成されているかを知る必要がないように、具象クラスの生成を分離します。
製品ファミリー内の複数のオブジェクトが連携して動作するように設計されている場合、クライアントは常に同じ製品ファミリーのオブジェクトのみを使用することが保証されます。
既存のシステムを変更することなく、開閉の原則に準拠した新しい製品ファミリを追加するのに非常に便利です。
欠点:
新しい製品レベルの構造を追加するのは面倒で、元のシステム、さらには抽象化層のコードに大幅な変更が必要ですが、これは明らかに大きな不便をもたらし、オープンとクローズの原則に違反します。
@製品ファミリーを追加
新しい製品ファミリを追加する場合、抽象ファクトリ パターンは開閉の原則を適切にサポートしており、既存のコードを変更することなく、特定の製品と対応する新しい特定のファクトリを追加するだけで済みます。
@新しい製品レベル構造を追加
新しい製品階層構造を追加するには、抽象ファクトリ クラスを含むすべてのファクトリ ロールを変更する必要があります。すべてのファクトリ クラスで、新しい製品を生産するためのメソッドを追加する必要があります。これは、オープンとクローズの原則に違反します。
ケース 1: (.NET コード)
コードのリストには次のものが含まれます。
プログラム.cs
using System;
using System.Configuration;
using System.Reflection;
namespace AbstractFactorySample
{
class Program
{
static void Main(string[] args)
{
//使用抽象层定义
SkinFactory factory;
Button bt;
TextField tf;
ComboBox cb;
//读取配置文件
string factoryType = ConfigurationManager.AppSettings["factory"];
//反射生成对象
factory = (SkinFactory)Assembly.Load("AbstractFactorySample").CreateInstance(factoryType);
bt = factory.CreateButton();
tf = factory.CreateTextField();
cb = factory.CreateComboBox();
bt.Display();
tf.Display();
cb.Display();
Console.Read();
}
}
}
ボタン.cs
namespace AbstractFactorySample
{
interface Button
{
void Display();
}
}
SpringButton.cs
using System;
namespace AbstractFactorySample
{
class SpringButton : Button
{
public void Display()
{
Console.WriteLine("显示浅绿色按钮。");
}
}
}
サマーボタン.cs
using System;
namespace AbstractFactorySample
{
class SummerButton : Button
{
public void Display()
{
Console.WriteLine("显示浅蓝色按钮。");
}
}
}
テキストフィールド.cs
namespace AbstractFactorySample
{
interface TextField
{
void Display();
}
}
SpringTextField.cs
using System;
namespace AbstractFactorySample
{
class SpringTextField : TextField
{
public void Display()
{
Console.WriteLine("显示绿色边框文本框。");
}
}
}
サマーテキストフィールド.cs
using System;
namespace AbstractFactorySample
{
class SummerTextField : TextField
{
public void Display()
{
Console.WriteLine("显示蓝色边框文本框。");
}
}
}
コンボボックス.cs
namespace AbstractFactorySample
{
interface ComboBox
{
void Display();
}
}
SpringComboBox.cs
using System;
namespace AbstractFactorySample
{
class SpringComboBox : ComboBox
{
public void Display()
{
Console.WriteLine("显示绿色边框组合框。");
}
}
}
SummerComboBox.cs
using System;
namespace AbstractFactorySample
{
class SummerComboBox : ComboBox
{
public void Display()
{
Console.WriteLine("显示蓝色边框组合框。");
}
}
}
スキンファクトリー.cs
namespace AbstractFactorySample
{
interface SkinFactory
{
Button CreateButton();
TextField CreateTextField();
ComboBox CreateComboBox();
}
}
SpringSkinFactory.cs
namespace AbstractFactorySample
{
class SpringSkinFactory : SkinFactory
{
public Button CreateButton()
{
return new SpringButton();
}
public TextField CreateTextField()
{
return new SpringTextField();
}
public ComboBox CreateComboBox()
{
return new SpringComboBox();
}
}
}
SummerSkinFactory.cs
namespace AbstractFactorySample
{
class SummerSkinFactory : SkinFactory
{
public Button CreateButton()
{
return new SummerButton();
}
public TextField CreateTextField()
{
return new SummerTextField();
}
public ComboBox CreateComboBox()
{
return new SummerComboBox();
}
}
}
アプリの構成
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="factory" value="AbstractFactorySample.SpringSkinFactory"/>
</appSettings>
</configuration>
ケース 2: (JAVA コード)
抽象的な工場
public interface IAnimalFactory {
ICat createCat();
IDog createDog();
}
コンクリート工場
public class BlackAnimalFactory implements IAnimalFactory {
public ICat createCat() {
return new BlackCat();
}
public IDog createDog() {
return new BlackDog();
}
}
public class WhiteAnimalFactory implements IAnimalFactory {
public ICat createCat() {
return new WhiteCat();
}
public IDog createDog() {
return new WhiteDog();
}
}
抽象的な製品
public interface ICat {
void eat();
}
public interface IDog {
void eat();
}
コンクリート製品
public class BlackCat implements ICat {
public void eat() {
System.out.println("The black cat is eating!");
}
}
public class WhiteCat implements ICat {
public void eat() {
System.out.println("The white cat is eating!");
}
}
public class BlackDog implements IDog {
public void eat() {
System.out.println("The black dog is eating");
}
}
public class WhiteDog implements IDog {
public void eat() {
System.out.println("The white dog is eating!");
}
}
テスト
public static void main(String[] args) {
IAnimalFactory blackAnimalFactory = new BlackAnimalFactory();
ICat blackCat = blackAnimalFactory.createCat();
blackCat.eat();
IDog blackDog = blackAnimalFactory.createDog();
blackDog.eat();
IAnimalFactory whiteAnimalF*ctory = new WhiteAnimalFactory();
ICat whiteCat = whiteAnimalFactory.createCat();
whiteCat.eat();
IDog whiteDog = whiteAnimalFactory.createDog();
whiteDog.eat();
}
プログラムが実行され、結果が返されます。
黒猫が食べてるよ! 黒い犬が食べています! 白猫が食べてるよ! 白い犬が食べています!