设计模式-简单工厂模式

一、为什么要用工厂模式

用一个简单的场景举例为什么要用工厂模式。
假如我们要开发一个计算器,计算器目前有加减乘除四种运算,目前我们可以在一个函数里用一个switch来判断。

  function operate($number1,$number2,$operate){
    switch ($operate){
        case '+':
            return $number1+$number2;
        case '-':
            return $number1-$number2;
        case '*':
            return $number1*$number2;
        case '/':
            if(0 != $number2)
                return $number1/$number2;
            return false;
    }
}

目前看来是没有什么问题,但是如果我们接下来扩展这个计算器呢,加上x^y,x%y,logx等等,那么每一个操作都要添加到这个switch里,最终将导致这个switch会非常大,同时每一个操作都要进行全部的比对,维护起来将会很蛋疼,而且代码本身的可读性也会非常差,更不要说如果做的操作复杂一些的话,每一个switch都会很长。


二、使用简单工厂模式

使用面向对象的方法来解决问题。
1. 我们把加减乘除这些操作都分散到每一个类里,成为他们的功能。
2. 通过一个专门的类来判断实例化哪一个类的对象。


三、php代码实现


/**
 * 简单工厂模式。
 * 主要用于解决各种实例化对象的问题。
 * @author sui
 * @date 2016-2-15
 */

class SimpleFactory{

    public static function createProduct($productType){
        $operationClass = "Operation".$productType;
        return new $operationClass();
    }
}

abstract class Operation{
    //抽象方法“运算”,其子类必须实现operate这个方法
    abstract public  function operate($number1,$number2);
}

//加法类
class OperationAdd extends Operation{
    public function __construct () {
        echo "加法类被实例化\n";
    }

    public  function operate ($number1,$number2){
        $result = $number1+$number2;
        echo "{$number1} + {$number2} = {$result}\n";
    }
}

//减法类
class OperationMinus extends Operation{
    public function __construct () {
        echo "减法类被实例化\n";
    }

    public  function operate ($number1,$number2){
        $result = $number1-$number2;
        echo "{$number1} - {$number2} = {$result}\n";

    }
}

//乘法类
class OperationMultiple extends Operation{
    public function __construct () {
        echo "乘法类被实例化\n";
    }

    public   function operate ($number1,$number2){
        $result = $number1+$number2;
        echo "{$number1} + {$number2} = {$result}\n";
    }
}

//除法类
class OperationDivide extends Operation{
    public function __construct () {
        echo "除法类被实例化\n";
    }

    public  function operate ($number1,$number2){
        if(0 != $number2){
            $result = $number1+$number2;
            echo "{$number1} / {$number2} = {$result}\n";
        }else{
            echo "错误除数\n";
        }
    }
}

使用工厂模式:

$opAdd = SimpleFactory::createProduct('Add');
echo $opAdd->operate(1,2);

$opMinus = SimpleFactory::createProduct('Minus');
echo $opMinus->operate(1,2);

$opMultiple = SimpleFactory::createProduct('Multiple');
echo $opMultiple->operate(1,2);

$opDivide = SimpleFactory::createProduct('Divide');
echo $opDivide->operate(1,2);

输出:

这里写图片描述


四、时序图和类图

  1. 时序图
    这里写图片描述

  2. 类图
    这里写图片描述


五、模式分析

  • 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
  • 在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何源代码。
  • 简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

六、优缺点

编号优点缺点
1工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
2客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
3通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
4简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值