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

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、总结

  • 通常我们把被创建的对象称之为【产品】
  • 创建【产品】的对象称为【工厂】
  • 当产品比较固定且数量少的情况下,我们只需要一个工厂类就可以,这个模式下我们称之为【简单工厂】
相关推荐
aq55356001 小时前
数字资源分发的技术革命与未来趋势
java·开发语言·python·php
JSON_L3 小时前
Laravel-Admin 语言改为中文(2)
php·laravel
阿桂有点桂3 小时前
Laravel队列再docker中开启和配置
docker·php·laravel
踩着两条虫4 小时前
VTJ 平台六大设计模式落地实战指南
开发语言·前端·人工智能·低代码·设计模式·重构·架构
眷蓝天4 小时前
K8S 单 Master 集群在 openEuler 24.03 上的部署指南
容器·kubernetes·php
石油人单挑所有6 小时前
基于多设计模式下的同步&异步日志系统测试报告
服务器·c++·vscode·设计模式
AI-小柒7 小时前
磅上线!DataEyes 聚合平台正式接入 GPT-Image-2,开启多模态 AI 生成全新纪元
大数据·开发语言·数据库·人工智能·gpt·php
JSON_L7 小时前
PHP 使用天地图
php·fastadmin
a里啊里啊7 小时前
软考-软件评测师:知识点整理(四)——信息安全知识
服务器·网络·计算机网络·php·哈希算法·软考·加密算法
weixin_430750938 小时前
部署FreeRadius+php+apache+mariaDB+daloradius 实现认证计费功能
php·apache·mariadb·daloradius·freeradius