您的当前位置:首页正文

【设计模式】抽象工厂模式

2024-11-02 来源:个人技术集锦

设计模式

 

1、定义

抽象工厂是一种创建型设计模式它能创建一系列相关的对象而无需指定其具体类。抽象工厂定义了用于创建不同产品的接口但将实际的创建工作留给了具体工厂类每个工厂类型都对应一个特定的产品变体

 

举个例子:

在本文提到的吉利和比亚迪都是汽车品牌。假设他们都可以自主生产汽车配件,那在组装汽车的时候只要固定在一个厂里调取配件,就不用担心用到其他厂商的配件,保证了整车都是用的一个品牌零部件。其中吉利和比亚迪就相当于两个具体的工厂,工厂可以生产很多的产品,如轮胎、车架、发动机等等。单把轮胎(系列产品中的抽象产品)拎出来看,轮胎就是一个系列,轮胎按照尺寸大小又分为18寸、20寸、22寸(这种具体尺寸的轮胎就是系列产品中的具体产品)等。

 

2、优缺点

  • 优点
    • 可以将产品生成代码抽取到同一位置使得代码易于维护
    • 向应用程序中引入新产品变体(特征)时无需修改客户端代码
    • 可以避免客户端和具体产品代码的耦合
    • 可以确保同一工厂生成的产品相互匹配
  • 缺点
    • 该模式需要向应用中引入众多接口和类代码可能会更加复杂

 

3、模式结构

  • 抽象工厂(AbstractFactory):抽象工厂接口声明了一组能返回不同抽象产品的方法。

  • 具体工厂(Concrete Factory):具体工厂可生成属于同一变体的系列产品。完成产品的创建。

  • 系列产品中的抽象产品:系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。

  • 系列产品中的具体产品:实现了抽象产品所定义的接口。

 

4、具体代码

抽象工厂(Abstract Factory):抽象工厂接口声明了一组能返回不同抽象产品的方法。

<?php

namespace app\admin\service\design_mode\abstract_factory_method;

interface AbstractFactory
{
    /**
     * 汽车轮胎
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/3/14 15:20
     */
    public function tyre();

    /**
     * 汽车车架
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/3/14 15:20
     */
    public function frame();

}

 

具体工厂(Concrete Factory):具体工厂可生成属于同一变体的系列产品。完成产品的创建。

<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 比亚迪工厂
 */
class BydFactory implements AbstractFactory
{
    public function tyre(): Tyre
    {
        return new BydTyre();
    }

    public function frame(): Frame
    {
        return new BydFrame();
    }
}
<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 吉利工厂
 */
class GeelyFactory implements AbstractFactory
{
    public function tyre(): Tyre
    {
        return new GeelyTyre();
    }

    public function frame(): Frame
    {
        return new GeelyFrame();
    }
}

 

系列产品中的抽象产品接口:系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。

<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 车架接口
 */
interface Frame
{
    /**
     * suv的车架
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/3/14 15:29
     */
    public function getSuvFrame();

    /**
     * 轿车的车架
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/3/14 15:29
     */
    public function getSedanFrame();
}
<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 轮胎接口
 */
interface Tyre
{
    /**
     * 18寸轮胎
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/3/14 15:31
     */
    public function get18Tyre();

    /**
     * 20寸轮胎
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/3/14 15:31
     */
    public function get20Tyre();

    /**
     * 22寸轮胎
     * @return mixed
     * @Author: fengzi
     * @Date: 2024/3/14 15:31
     */
    public function get22Tyre();
}

 

系列产品中的具体产品:实现了抽象产品所定义的接口。

<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 比亚迪车架
 */
class BydFrame implements Frame
{

    public function getSuvFrame()
    {
        echo "比亚迪SUV车架".PHP_EOL;
    }

    public function getSedanFrame()
    {
        echo "比亚迪轿车车架".PHP_EOL;
    }
}
<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 比亚迪造轮胎
 */
class BydTyre implements Tyre
{
    public function get18Tyre()
    {
        echo "比亚迪18寸轮胎".PHP_EOL;
    }

    public function get20Tyre()
    {
        echo "比亚迪20寸轮胎".PHP_EOL;
    }

    public function get22Tyre()
    {
        echo "比亚迪22寸轮胎".PHP_EOL;
    }
}
<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 吉利车架
 */
class GeelyFrame implements Frame
{
    public function getSuvFrame()
    {
        echo "吉利SUV车架".PHP_EOL;
    }

    public function getSedanFrame()
    {
        echo "吉利轿车车架".PHP_EOL;
    }
}
<?php

namespace app\admin\service\design_mode\abstract_factory_method;

/**
 * 吉利轮胎
 */
class GeelyTyre implements Tyre
{
    public function get18Tyre()
    {
        echo "吉利18寸轮胎".PHP_EOL;
    }

    public function get20Tyre()
    {
        echo "吉利20寸轮胎".PHP_EOL;
    }

    public function get22Tyre()
    {
        echo "吉利22寸轮胎".PHP_EOL;
    }
}

 

客户端调用代码

<?php

namespace app\admin\controller\design_mode;

use app\admin\service\design_mode\abstract_factory_method\BydFactory;
use app\admin\service\design_mode\abstract_factory_method\GeelyFactory;

/**
 * 抽象工厂模式
 */
class AbstractFactoryMethodController
{
    /**
     * 调用抽象工厂模式
     * @return void
     * @Author: fengzi
     * @Date: 2024/3/14 15:39
     */
    public function index()
    {
        //比亚迪造车
        $factory = new BydFactory();
        $tyre = $factory->tyre();
        $frame = $factory->frame();
        $tyre->get18Tyre();
        $frame->getSedanFrame();
        echo '---------------'.PHP_EOL;
        $tyre->get22Tyre();
        $frame->getSuvFrame();

        echo '==========================='.PHP_EOL;

        //吉利造车
        $factory = new GeelyFactory();
        $tyre = $factory->tyre();
        $frame = $factory->frame();
        $tyre->get18Tyre();
        $frame->getSedanFrame();
        echo '---------------'.PHP_EOL;
        $tyre->get22Tyre();
        $frame->getSuvFrame();
    }

}

 

客户端调用结果展示:

 

显示全文