【设计模式】工厂方法模式

1、定义

工厂方法 模式 是一种创建型的设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。其实就把产品对象的实际创建工作放到具体的子类工厂当中实现。

2、优缺点

  • 优点:
    • 可以避免创建者和具体产品之间的紧密耦合。
    • 单一职责原则。可以将产品创建代码放在程序的单一位置,从而使得代码更容易维护。
    • 开闭原则。无需更改现有客户端代码,就可以在程序中引入新的产品类型。
  • 缺点:
    • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,增加了系统的复杂度。

3、模式结构

  • 抽象工厂(Abstract Factory):提供一个创建产品的接口。调用者可以通过它访问具体工厂的工厂方法。
  • 具体工厂(Concrete Factory):继承自抽象工厂,并实现其创建对象的方法。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(Concrete Product):实现了抽象产品中所定义的接口,由具体工厂来创建,与同具体工厂之间是一一对应的。

4、具体代码

1、抽象工厂(Abstract Factory):提供一个创建产品的接口。调用者可以通过它访问具体工厂的工厂方法。

复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:55
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 抽象工厂类
 */
abstract class CarFactory
{
    abstract public function createCar(): Car;
}

2、具体工厂(Concrete Factory):继承自抽象工厂,并实现其创建对象的方法。

复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:55
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 宝马工厂
 *
 * 具体工厂类,继承自抽象工厂
 */
class BmwFactory extends CarFactory
{

    public function createCar(): Car
    {
        // TODO: Implement createCar() method.
        return new Bmw();
    }
}
复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:55
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 奔驰工厂
 *
 * 具体工厂类,继承自抽象工厂
 */
class BenzFactory extends CarFactory
{

    public function createCar(): Car
    {
        // TODO: Implement createCar() method.
        return new Benz();
    }
}

3、抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。

复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:21
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 抽象产品类
 */
abstract class Car
{
    /**
     * 给汽车加油
     * 抽象方法,用于实现产品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function refuel();

    /**
     * 驾驶汽车
     * 抽象方法,用于实现产品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function drive();
}

4、具体产品(Concrete Product):实现了抽象产品中所定义的接口,由具体工厂来创建,与同具体工厂之间是一一对应的。

复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具体产品类-宝马汽车
 */
class Bmw extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo  "给宝马车加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo  "驾驶宝马车\n";
    }
}
复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具体产品类-奔驰汽车
 */
class Benz extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo "给奔驰车加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo "驾驶奔驰车\n";
    }
}

5、调用方式

复制代码
<?php
/**
 * 工厂方法模式
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:16
 */

namespace app\admin\controller\design_mode;

use app\admin\service\design_mode\factory_method\BenzFactory;
use app\admin\service\design_mode\factory_method\BmwFactory;

class FactoryMethodController
{
    /**
     * 调用工厂方法模式
     * @return void
     * @Author: fengzi
     * @Date: 2024/2/26 9:56
     */
    public function index()
    {
        //调用奔驰方法
        $factory = new BenzFactory();
        $car = $factory->createCar();
        $car->refuel();
        $car->drive();

        //调用宝马方法
        $factory = new BmwFactory();
        $car = $factory->createCar();
        $car->refuel();
        $car->drive();
    }
}

6、调用结果展示:

5、工厂方法模式的精简版 - 简单工厂模式

简单工厂模式中的每个产品不用像工厂方法模式一样每个产品都对应一个工厂类,只需要通过一个工厂方法来判断性的创建对应产品。具体请看以下代码。

1、抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。

复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:21
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 抽象产品类
 */
abstract class Car
{
    /**
     * 给汽车加油
     * 抽象方法,用于实现产品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function refuel();

    /**
     * 驾驶汽车
     * 抽象方法,用于实现产品的功能
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/2/23 11:26
     */
    public abstract function drive();
}

2、具体产品(Concrete Product):实现了抽象产品中所定义的接口,由一个工厂方法来创建产品对象。

复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具体产品类-奔驰汽车
 */
class Benz extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo "给奔驰车加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo "驾驶奔驰车\n";
    }
}
复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/23
 * Time: 11:22
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 具体产品类-宝马汽车
 */
class Bmw extends Car
{

    public function refuel()
    {
        // TODO: Implement refuel() method.
        echo  "给宝马车加油\n";
    }

    public function drive()
    {
        // TODO: Implement drive() method.
        echo  "驾驶宝马车\n";
    }
}

3、简单工厂的工厂类

复制代码
<?php
/**
 * Created by PhpStorm
 * Author: fengzi
 * Date: 2024/2/26
 * Time: 10:17
 */

namespace app\admin\service\design_mode\factory_method;

/**
 * 简单工厂类
 */
class SimpleFactory
{
    /**
     * 简单工厂模式
     * @param string $type  产品类型:benz奔驰,bmw宝马
     * @return string|void
     * @Author: fengzi
     * @Date: 2024/2/26 10:15
     */
    public function getProduct(string $type): Car
    {
        switch ($type)
        {
            case 'benz':
                return new Benz();
                break;
            case 'bmw':
                return new Bmw();
                break;
            default:
                return '';
        }
    }
}

4、调用方式

复制代码
<?php
/**
 * 简单工厂模式
 * Author: fengzi
 * Date: 2024/2/22
 * Time: 17:16
 */

namespace app\admin\controller\design_mode;

use app\admin\service\design_mode\factory_method\SimpleFactory;

class FactoryMethodController
{
    /**
     * 简单工厂模式
     * @Author: fengzi
     * @Date: 2024/2/26 10:15
     */
    public function simpleFactory()
    {
        $simpleFactory = new SimpleFactory();
        //调用奔驰方法
        $benz = $simpleFactory->getProduct('benz');
        $benz->refuel();
        $benz->drive();

        //调用宝马方法
        $bmw = $simpleFactory->getProduct('bmw');
        $bmw->refuel();
        $bmw->drive();
    }
}

5、调用结果展示

6、总结

  • 通常我们把被创建的对象称之为【产品】
  • 创建【产品】的对象称为【工厂】
  • 当产品比较固定且数量少的情况下,我们只需要一个工厂类就可以,这个模式下我们称之为【简单工厂】
相关推荐
ttod_qzstudio5 小时前
【软考设计模式】备忘录模式:对象状态的捕获与无损恢复精讲
设计模式·备忘录模式
ttod_qzstudio6 小时前
【软考设计模式】责任链模式:请求传递的多级处理与发送接收解耦精讲
设计模式·责任链模式
2501_914245936 小时前
C语言设计模式详解:从理论到实践的完整指南
c语言·开发语言·设计模式
IpdataCloud6 小时前
跨区服玩家延迟高怎么办?用IP离线库自动分配到最近服务器
数据库·tcp/ip·github·php·ip
辣椒思密达7 小时前
AI出海产品本地化测试:住宅IP在模拟海外用户环境中的实践价值
网络协议·tcp/ip·安全·php·苹果vision pro
bitbrowser8 小时前
Claude 账号频繁被封?转向国内可直接使用的 AI 工具
开发语言·php
2501_912784088 小时前
Laravel 多渠道代购订单聚合队列踩坑实战,解决跨平台漏单与同步
php·laravel·taocarts
2401_854151558 小时前
嵌入式 Bootloader 与 OTA 固件升级深度解析——从 Flash 分区到安全回滚
开发语言·stm32·单片机·嵌入式硬件·安全·php
CaffeinePro10 小时前
四⼤极简架构原则KISS/DRY/YAGNI/LOD
设计模式·架构
霸道流氓气质11 小时前
SpringBoot中设计模式组合使用示例-策略、模板、观察者、门面、工厂、单例。
spring boot·后端·设计模式