DEV Community

菜皮日记
菜皮日记

Posted on

创建型设计模式-工厂方法 Factory Method

简介

工厂方法中,每一个具体工厂类都对应创建一个具体产品类,所有具体工厂类都实现抽象工厂,所有具体产品类都实现抽象产品。

抽象工厂定义了创建抽象产品的方法签名,具体工厂类各自实现各自逻辑,来创建具体的产品。

角色

  • 抽象工厂 Abstract Factory

    定义创建产品的方法签名,即Factory Method

  • 抽象产品 Abstract Product

    定义产品的基本属性

  • 具体工厂 Concrete Factory

    实现自抽象工厂,并实现 Factory Method,实现如何创建具体产品。

  • 具体产品 Concrete Product

    实现具体产品基本属性

类图

如图所示,Dialog抽象工厂可以创建Button抽象产品,WindowsDialog和WebDialog都是具体工厂,负责创建WindownsButton和HTMLButton。

https://deb-gmi.oss-cn-beijing.aliyuncs.com/img/20210408160238.png

代码

abstract class Creator
{
    abstract public function factoryMethod(): Product;

    public function someOperation(): string
    {
        $product = $this->factoryMethod();
        $result = "Creator: The same creator's code has just worked with " . $product->operation();
        return $result;
    }
}

class ConcreteCreator1 extends Creator
{
    public function factoryMethod(): Product
    {
        return new ConcreteProduct1();
    }
}

class ConcreteCreator2 extends Creator
{
    public function factoryMethod(): Product
    {
        return new ConcreteProduct2();
    }
}

interface Product
{
    public function operation(): string;
}

class ConcreteProduct1 implements Product
{
    public function operation(): string
    {
        return "{Result of the ConcreteProduct1}";
    }
}

class ConcreteProduct2 implements Product
{
    public function operation(): string
    {
        return "{Result of the ConcreteProduct2}";
    }
}

function clientCode(Creator $creator)
{
    echo "Client: I'm not aware of the creator's class, but it still works.\n" . $creator->someOperation() . "\n";
}

echo "App: Launched with the ConcreteCreator1.\n";
clientCode(new ConcreteCreator1());

echo "App: Launched with the ConcreteCreator2.\n";
clientCode(new ConcreteCreator2());
Enter fullscreen mode Exit fullscreen mode

output

App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
Enter fullscreen mode Exit fullscreen mode

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

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