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

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

抽象工厂模式( Abstract Factor Pattern),可简单理解为工厂模式的升级版

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

1,工厂模式可以将对象的生产从直接new 一个对象,改成通过调用一个工厂方法生产。这样的封装,代码若需修改new的对象时,不需修改多处new语句,只需更改生产对象方法。

2,若所需实例化的对象可选择来自不同的类,可省略if-else多层判断,给工厂方法传入对应的参数,利用多态性,实例化对应的类。

(二)工厂模式结构图

1,工厂方法模式

2,抽象工厂模式

(三)简单实现代码

//工厂类
class Factor{   
    //生成对象方法
    static function createDB(){
        echo '我生产了一个DB实例';
        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 Add extends Operation{
    public function getVal($i, $j)
    {
        return $i + $j;
    }
}
class Minus  extends Operation{
    public function getVal($i, $j)
    {
        return $i - $j;
    }
}
class Multiplied extends Operation{
    public function getVal($i, $j)
    {
        return $i * $j;
    }
}

class Divide extends Operation{
    public function getVal($i, $j)
    {
        if ($j == 0)
            throw new Exception("被除数不能为0");
        return $i / $j;
    }
}
class CalcFactor{
    private static $operation;
    public static function createOperation(string $operation){
        switch ($operation){
            case "+":
                self::$operation = new Add();
                break;
            case "-":
                self::$operation = new Minus();
                break;
            case "*":
                self::$operation = new Multiplied();
                break;
            case "/":
                self::$operation = new Divide();
                break;
        }
        return self::$operation;
    }
}
$calc = CalcFactor::createOperation('/');
echo $calc->getVal(1,0);

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

解决方法:

(1):通过传入指定类名

abstract class Operation{
    abstract public function getVal($i, $j);
}
class Add extends Operation{
    public function getVal($i, $j)
    {
        return $i + $j;
    }
}
class Minus  extends Operation{
    public function getVal($i, $j)
    {
        return $i - $j;
    }
}
class Multiplied extends Operation{
    public function getVal($i, $j)
    {
        return $i * $j;
    }
}

class Divide extends Operation{
    public function getVal($i, $j)
    {
        if ($j == 0)
            throw new Exception("被除数不能为0");
        return $i / $j;
    }
}
class CalcFactor{
    public static function createOperation(string $operation){
                return new $operation;
    }
}
$calc = CalcFactor::createOperation("Divide");
echo $calc->getVal(1,1);

(2):通过抽象工厂模式

这里顺带提一个问题:如果我系统还有个生产一个文本输入器工厂,那么那个工厂和这个计数器工厂又有什么关系呢。

抽象高于实现

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

// 抽象运算类
abstract class Operation{
    abstract public function getVal($i, $j);
}
// 加法类
class Add extends Operation{
    public function getVal($i, $j)
    {
        return $i + $j;
    }
}
// 减法类
class Minus  extends Operation{
    public function getVal($i, $j)
    {
        return $i - $j;
    }
}
// 乘法类
class Multiplied extends Operation{
    public function getVal($i, $j)
    {
        return $i * $j;
    }
}
// 除法类
class Divide extends Operation{
    public function getVal($i, $j) 
    {
        if ($j == 0)
            throw new Exception("被除数不能为0");
        return $i / $j;
    }
}
// 抽象工厂类
abstract class Factor{
    abstract static function getInstance();
}
// 加法工厂类
class AddFactor extends Factor {
    public static function getInstance()
    {
        return new Add();
    }
}
// 减法工厂类
class MinusFactor extends Factor {
    public static function getInstance()
    {
        return new Minus();
    }
}
// 乘法工厂类
class MultipliedFactor extends Factor {
    public static function getInstance()
    {
        return new Multiplied();
    }
}
// 除法工厂类
class DivideFactor extends Factor {
    public static function getInstance()
    {
        return new Divide();
    }
}

$divide = DivideFactor::getInstance();
echo $divide->getVal(1,1);

第四节 PHP设计模式(三)—外观模式(门面模式)(Facade Pattern)

参考资料:

https://design-patterns.readthedocs.io

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值