PHP设计模式(二)——工厂模式(Factor Pattern)

@[TOC](PHP设计模式(二)——工厂模式(Factor Pattern))

工厂模式(Factor Pattern),就是负责生成其他对象的类或方法

(一)为什么需要工厂模式

  1. 工厂模式可以将对象的生产从直接new 一个对象,改成通过调用一个工厂方法生产。这样的封装,代码若需修改new的对象时,不需修改多处new语句,只需更改生产对象方法。
  2. 若所需实例化的对象可选择来自不同的类,可省略if-else多层判断,给工厂方法传入对应的参数,利用多态性,实例化对应的类。

(二)简单实现代码

// 工厂类
class Factor
{
    static function createDb()
    {
        echo '我生产了一个实例——';
        return new DB();
    }
}

// 数据库类
class DB
{
    public function __construct()
    {
        echo __CLASS__.PHP_EOL;
    }
}

$db = Factor::createDb();

(三)实现一个运算器

// 抽象运算类
abstract class Operation
{
    abstract public function getVal($i, $j);
}

// 继承抽象类的 加法类
class OperationAdd extends Operation
{
    public function getVal($i, $j)
    {
        return $i + $j;
    }
}

// 继承抽象类的 减法类
class OperationSub extends Operation
{
    public function getVal($i, $j)
    {
        return $i - $j;
    }
}

// 计算器工厂
class CounterFactor
{
    private static $operation;

    // 工厂生产特定类对象方法
    static function createOperation(string $operation)
    {
        switch ($operation) {
            case '+' :
                self::$operation = new OperationAdd();
                break;
            case '-' :
                self::$operation = new OperationSub();
                break;
        }
        return self::$operation;
    }
}

$counter = CounterFactor::createOperation('-');
echo $counter->getVal(1, 2);

缺点:若是再增加一个乘法运算,除了增加一个乘法运算类之外,还得去工厂生产方法里面添加对应的case代码,违反了开放-封闭原则。

解决方法(1):通过传入指定类名

abstract class Operation
{
    abstract public function getVal($i, $j);
}

// 继承抽象类的 加法类
class OperationAdd extends Operation
{
    public function getVal($i, $j)
    {
        return $i + $j;
    }
}

// 继承抽象类的 减法类
class OperationSub extends Operation
{
    public function getVal($i, $j)
    {
        return $i - $j;
    }
}

// 继承抽象类的 乘法类
class OperationMul extends Operation
{
    public function getVal($i, $j)
    {
        return $i * $j;
    }
}

// 计算器工厂
class CounterFactor
{
    // 工厂生产特定类对象方法
    static function createOperation(string $operation)
    {
        return new $operation;
    }
}

$counter = CounterFactor::createOperation('OperationMul');
echo $counter->getVal(1, 2);

解决方法(2):通过抽象工厂模式

抽象高于实现

其实我们完全可以抽象出一个抽象工厂,然后将对应的对象生产交给子工厂实现。代码如下

<?php

abstract class Operation
{
    abstract public function getVal($i, $j);
}

// 继承抽象类的 加法类
class OperationAdd extends Operation
{
    public function getVal($i, $j)
    {
        return $i + $j;
    }
}

// 继承抽象类的 减法类
class OperationSub extends Operation
{
    public function getVal($i, $j)
    {
        return $i - $j;
    }
}

// 继承抽象类的 乘法类
class OperationMul extends Operation
{
    public function getVal($i, $j)
    {
        return $i * $j;
    }
}

// 继承抽象类的 除法类
class OperationDiv extends Operation
{
    public function getVal($i, $j)
    {
        return $i / $j;
    }
}

// 抽象工厂类
abstract class Factor
{
    abstract static function getInstance();
}

// 加法子工厂
class AddFactor extends Factor
{
    // 工厂生产特定类对象方法
    static function getInstance()
    {
        return new OperationAdd();
    }
}

// 减法子工厂
class SubFactor extends Factor
{
    // 工厂生产特定类对象方法
    static function getInstance()
    {
        return new OperationSub();
    }
}

// 乘法子工厂
class MulFactor extends Factor
{
    // 工厂生产特定类对象方法
    static function getInstance()
    {
        return new OperationMul();
    }
}

// 除法子工厂
class DivFactor extends Factor
{
    // 工厂生产特定类对象方法
    static function getInstance()
    {
        return new OperationDiv();
    }
}

echo AddFactor::getInstance()->getVal(1, 2).PHP_EOL;
echo SubFactor::getInstance()->getVal(1, 2).PHP_EOL;
echo MulFactor::getInstance()->getVal(1, 2).PHP_EOL;
echo DivFactor::getInstance()->getVal(1, 2).PHP_EOL;

猜你喜欢

转载自blog.csdn.net/qq_14824885/article/details/82841094