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

  工厂模式(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 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):通过传入指定类名

//计算器工厂
class CounterFactor {
    //工厂生产特定类对象方法
    static function createOperation(string $operation){
        return new $operation;
    }
}
class OperationMul extends Operation{
    public function getVal($i,$j){
        return $i*$j;
    }
}
$counter = CounterFactor::createOperation('OperationMul');

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

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

  抽象高于实现

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

//抽象运算类
abstract class Operation{
    abstract public function getVal($i,$j);//抽象方法不能包含方法体
}
//加法类
class OperationAdd extends Operation{
    public function getVal($i,$j){
        return $i+$j;
    }
}
//乘法类
class OperationMul 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 MulFactor extends Factor {
    static function getInstance(){
        return new OperationMul;
    }
}
//文本输入器生产工厂
class TextFactor extends Factor{
    static function getInstance(){}
}
$mul = MulFactor::getInstance();
echo $mul->getVal(1,2);

来源:慕课手记 https://www.imooc.com/article/16971


转载请注明出处:https://www.onexin.net/php-factor-pattern/

相关文章:

1、用 PHP 编写更好的正则表达式regex
https://www.onexin.net/php-regex/

2、PHP 版本 8.2,8.1,8.0,7.4
https://www.onexin.net/php-8_2-8_1-8_0-7_4/

3、PHP中的Liskov替换原则
https://www.onexin.net/php-liskov/

4、php实现自运行的do实例详解
https://www.onexin.net/php-do/

5、PHP 后端实现JWT认证方法示例
https://www.onexin.net/php-jwt/

Leave a Reply