设计模式详解 PHP版
  • 设计模式简介&原则
  • 常见设计模式
    • 工厂模式(Factory)
      • 简单工厂模式(Simple Factory)
      • 工厂方法模式(Factory Method)
      • 抽象工厂模式(Abstract Factory)
      • 三种工厂模式对比
    • 单例模式(Singleton)
      • 场景*memcache操作类
    • 注册树模式
    • 适配器模式(Adapter)
    • 策略模式(Strategy)
    • 数据对象映射模式
    • 观察者模式(observer)
    • 原型模式(Prototype)
    • 装饰器模式(Decorator)
    • 迭代器模式 (Iteration)
    • 桥接模式(Bridge)
    • 建造者模式(Builder)
    • 命令行模式(Command)
    • 组合模式(Composite)
    • 外观模式(Facade)
    • 享元模式(Flyweight)
    • 解释器模式(Interpreter)
    • 中介者模式(Mediator)
    • 备忘录模式(Memento)
    • 代理模式(Proxy)
    • 责任链模式(Responsibility Chain)
    • 状态模式(State)
    • 模板方法模式(Template Method)
    • 访问者模式(Visitor)
  • 资料
Powered by GitBook
On this page
  • 简单工厂模式
  • 工厂方法模式

Was this helpful?

  1. 常见设计模式
  2. 工厂模式(Factory)

三种工厂模式对比

例子来自<大话设计模式>一书,php代码由个人实现

简单工厂模式:

  • 一个抽象产品类(可以是:接口,抽象类,普通类),可以派生出多个具体产品类。

  • 单独一个具体的工厂类。

  • 每个具体工厂类只能创建一个具体产品类的实例。

工厂方法模式:

  • 一个抽象产品类(可以是:接口,抽象类,普通类),可以派生出多个具体产品类。

  • 一个抽象工厂类(可以是:接口,抽象类),可以派生出多个具体工厂类。

  • 每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:

  • 多个抽象产品类(可以是:接口,抽象类,普通类),每个抽象产品类可以派生出多个具体产品类。

  • 一个抽象工厂类(可以是:接口,抽象类),可以派生出多个具体工厂类。

  • 每个具体工厂类可以创建多个具体产品类的实例。

区别:

  • 简单工厂模式只有一个抽象产品类,只有一个具体的工厂类。

  • 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。

  • 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个具体产品类的实例。

简单工厂模式

UML类图如下:

当需要加法类的时候,调用工厂类的CreateOperate(),要指定制造的Product

调用工厂,需要createOperator("/"),就能返回除法运算符。

  • 优点:客户端不需要修改代码。

  • 缺点: 当需要增加新的运算类的时候,不仅需新加运算类,还要修改工厂类,违反了开闭原则。

简单工厂模式程序设计图:

具体实现:

1)抽象产品(Product)角色:运算抽象类(Operation)。

// 运算抽象类
class Operation{

    // 数字A
    protected $_numberA = null;

    // 数字B
    protected $_numberB = null;

    /**
     * 设置成员A
     *
     * @param double $num 数字
     * @return void
     */
    public function setNumberA($num){
        $this->_numberA = $num;
    }

    /**
     * 获取成员A
     *
     * @return double 数字
     */
    public function getNumberA(){
        return $this->_numberA;
    }

    /**
     * 设置成员B
     *
     * @param double $num 数字
     * @return void
     */
    public function setNumberB($num){
        $this->_numberB = $num;
    }

    /**
     * 获取成员B
     *
     * @return double 数字
     */
    public function getNumberB(){
        return $this->_numberA;
    }

    /**
     * 获取运算结果
     *
     * @return double 数字
     */
    public function getResult(){
        return null;
    }
}

2)具体产品(Concrete Product)角色:加法运算(OperationAdd),减法运算(OperationSub),乘法运算(OperationMul),除法运算(OperationDiv)。

// 加法类
class OperationAdd extends Operation{

    /**
     * 获取运算结果
     *
     * @return double 数字
     */
    public function getResult(){
        return $this->_numberA + $this->_numberB;
    }
}

// 减法类
class OperationSub extends Operation{

    /**
     * 获取运算结果
     *
     * @return double 数字
     */
    public function getResult(){
        return $this->_numberA - $this->_numberB;
    }
}

// 乘法类
class OperationMul extends Operation{

    /**
     * 获取运算结果
     *
     * @return double 数字
     */
    public function getResult(){
        return $this->_numberA * $this->_numberB;
    }
}

// 除法类
class OperationDiv extends Operation{

    /**
     * 获取运算结果
     *
     * @return double 数字
     */
    public function getResult(){
        if ($this->_numberB == 0) {
            return null;
        }
        return $this->_numberA / $this->_numberB;
    }
}

3)工厂(Creator)角色:工厂类(OperationFactory)。

/**
 *
 * 设计模式:简单工厂模式
 * 
 * 模式简介:用一个单独的类来创造实例化的过程,叫做简单工厂。好处将来增加或减少
 * 实例只需要修改工厂即可。
 *
 */


// 创建一个工程,用来生产实例
class OperationFactory{

    /**
     * 根据运算不同实例不同的对象
     *
     * @return object 返回实例化的对象
     */
    public static function createOperate($operate){
        $oper = null;
        switch ($operate) {

            // 实例加法类
            case '+' :
                $oper = new OperationAdd();
                break;

            // 实例减法类
            case '-' :
                $oper = new OperationSub();
                break;

            // 实例乘法类
            case '*' :
                $oper = new OperationMul();
                break;

            // 实例乘法类
            case '/' :
                $oper = new OperationDiv();
                break;

            default :
                $oper = null;
        }

        return $oper;
    }
}

/*
* 客户端
*
*/
// 工厂创建实例
$operObject = OperationFactory::createOperate('+');

if ($operObject == null) {
    return '$operate not found';
}

// 设置数字A
$operObject->setNumberA(5);

// 设置数字B
$operObject->setNumberB(2);

// 运算
echo $operObject->getResult() . "\n";

工厂方法模式

UML类图如下:

这个和简单工厂有区别,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂

  • 好处:增加一个运算类(例如N次方类),只需要增加运算类和相对应的工厂,两个类,不需要修改工厂类。

  • 缺点:增加运算类,会修改客户端代码,工厂方法只是把简单工厂的内部逻辑判断移到了客户端进行。

改造简单工厂代码中的工厂(Creator)角色,代码如下:

interface IFactory
{
    public function CreateOperation();
}

class AddFactory implements IFactory
{
    public function CreateOperation()
    {
        return new OperationAdd();
    }
}

class SubFactory implements IFactory
{
    public function CreateOperation()
    {
        return new OperationSub();
    }
}

class MulFactory implements IFactory
{
    public function CreateOperation()
    {
        return new OperationMul();
    }
}

class DivFactory implements IFactory
{
    public function CreateOperation()
    {
        return new OperationDiv();
    }
}

/*
 * 客户端代码
 * 
 * */

// 工厂创建实例
$operationFactory = new AddFactory();
$operation = $operationFactory->CreateOperation();
// 设置数字A
$operation->setNumberA(10);
// 设置数字B
$operation->setNumberB(10);
// 运算
echo $operation->getResult() . "\n";

抽象工厂模式:

Previous抽象工厂模式(Abstract Factory)Next单例模式(Singleton)

Last updated 6 years ago

Was this helpful?

UML类图如下: