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


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

    • 通常我们把被创建的对象称之为【产品】
    • 创建【产品】的对象称为【工厂】
    • 当产品比较固定且数量少的情况下,我们只需要一个工厂类就可以,这个模式下我们称之为【简单工厂】

     

  • 相关阅读:
    MySQL binlog模式及主备的基本原理
    一次明白 JDBC,ORM,JPA,SpringDataJPA 之间的关系
    计算机网络 —— 运输层(TCP三次握手)
    UE5学习(游戏存档,两种适应性的射线检测,时间膨胀)
    3 CSS
    frp内网穿透教程2022最新(含内网ssh配置与msf联动配置)
    2024/2/29 备战蓝桥杯 6-1 二分
    来自中科院的一次java技术面经历
    区块链技术在供应链管理中的创新应用
    Vue3 环境变量
  • 原文地址:https://www.cnblogs.com/mklblog/p/18029716