简介
拿工厂方法模式作对比,在工厂方法模式中,一个工厂只能创建一种产品,如椅子工厂只能创建椅子。而抽象工厂可以创建一系列产品,如家具工厂可以创建椅子,桌子,床等等。
抽象工厂类负责定义可以创建的抽象产品类,具体工厂编写不同风格(即各自的业务逻辑)的创建产品的过程。
角色
-
抽象工厂
定义工厂可以生产的抽象产品,多个产品则对应多个创建方法
-
抽象产品
与工厂方法模式中没什么区别,简单定义类属性即可
可能有多个,抽象椅子,抽象桌子,抽象床等
-
具体工厂
分别实现抽象工厂中定义的创建产品的方法
可能有多个,按照不同风格或叫不同业务逻辑,创建一组产品,如古典工厂创建古典风格椅子、桌子、床,现代工厂创建现代风格桌椅床。
-
具体产品
实现抽象产品即可
可能有多个,现代风格桌子、古典风格椅子等等
类图
图中展示,GUIFactory 抽象工厂定义可以创建 Button 和 Checkbox 抽象产品。
具体工厂WinFactory可以创建出 Win 风格的 WinButton 和 WinCheckbox,MacFatory 可以创建出 Mac 风格的 MacButton 和 MacCheckbox。
代码
interface AbstractFactory
{
public function createProductA(): AbstractProductA;
public function createProductB(): AbstractProductB;
}
class ConcreteFactory1 implements AbstractFactory
{
public function createProductA(): AbstractProductA
{
return new ConcreteProductA1();
}
public function createProductB(): AbstractProductB
{
return new ConcreteProductB1();
}
}
class ConcreteFactory2 implements AbstractFactory
{
public function createProductA(): AbstractProductA
{
return new ConcreteProductA2();
}
public function createProductB(): AbstractProductB
{
return new ConcreteProductB2();
}
}
interface AbstractProductA
{
public function usefulFunctionA(): string;
}
class ConcreteProductA1 implements AbstractProductA
{
public function usefulFunctionA(): string
{
return "The result of the product A1.";
}
}
class ConcreteProductA2 implements AbstractProductA
{
public function usefulFunctionA(): string
{
return "The result of the product A2.";
}
}
interface AbstractProductB
{
public function usefulFunctionB(): string;
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string;
}
class ConcreteProductB1 implements AbstractProductB
{
public function usefulFunctionB(): string
{
return "The result of the product B1.";
}
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string
{
$result = $collaborator->usefulFunctionA();
return "The result of the B1 collaborating with the ({$result})";
}
}
class ConcreteProductB2 implements AbstractProductB
{
public function usefulFunctionB(): string
{
return "The result of the product B2.";
}
public function anotherUsefulFunctionB(AbstractProductA $collaborator): string
{
$result = $collaborator->usefulFunctionA();
return "The result of the B2 collaborating with the ({$result})";
}
}
function clientCode(AbstractFactory $factory)
{
$productA = $factory->createProductA();
$productB = $factory->createProductB();
echo $productB->usefulFunctionB() . "\n";
echo $productB->anotherUsefulFunctionB($productA) . "\n";
}
echo "Client: Testing client code with the first factory type:\n";
clientCode(new ConcreteFactory1());
echo "Client: Testing the same client code with the second factory type:\n";
clientCode(new ConcreteFactory2());
output:
Client: Testing client code with the first factory type:
The result of the product B1.
The result of the B1 collaborating with the (The result of the product A1.)
Client: Testing the same client code with the second factory type:
The result of the product B2.
The result of the B2 collaborating with the (The result of the product A2.)
Top comments (0)