设计模式-简单工厂模式

来源:互联网 发布:java的compare方法 编辑:程序博客网 时间:2024/05/21 08:45

一、为什么要用工厂模式

用一个简单的场景举例为什么要用工厂模式。
假如我们要开发一个计算器,计算器目前有加减乘除四种运算,目前我们可以在一个函数里用一个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
原创粉丝点击