DEV Community

菜皮日记
菜皮日记

Posted on

创建型设计模式-抽象工厂 Abstract Factory

简介

拿工厂方法模式作对比,在工厂方法模式中,一个工厂只能创建一种产品,如椅子工厂只能创建椅子。而抽象工厂可以创建一系列产品,如家具工厂可以创建椅子,桌子,床等等。

抽象工厂类负责定义可以创建的抽象产品类,具体工厂编写不同风格(即各自的业务逻辑)的创建产品的过程。

角色

  • 抽象工厂

    定义工厂可以生产的抽象产品,多个产品则对应多个创建方法

  • 抽象产品

    与工厂方法模式中没什么区别,简单定义类属性即可

    可能有多个,抽象椅子,抽象桌子,抽象床等

  • 具体工厂

    分别实现抽象工厂中定义的创建产品的方法

    可能有多个,按照不同风格或叫不同业务逻辑,创建一组产品,如古典工厂创建古典风格椅子、桌子、床,现代工厂创建现代风格桌椅床。

  • 具体产品

    实现抽象产品即可

    可能有多个,现代风格桌子、古典风格椅子等等

类图

图中展示,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());
Enter fullscreen mode Exit fullscreen mode

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.)
Enter fullscreen mode Exit fullscreen mode

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay