您的位置 首页 php

php设计模式——简单工厂模式

简单工厂是什么?

简单工厂是由三部分组成:

  1. 1个工厂类
  2. 1个接口类或抽象类
  3. 多个具体实现

各部分之间的关系:

  1. 接口或抽象类定义待开发功能的整体结构,需要哪些实现
  2. 多个具体实现继承接口或抽象类具体实现功能。
  3. 简单工厂来创建具体实现的实例进行调用

关系图:

简单工厂有什么用?

最常用的就是用于流程控制解耦,比如输入一个参数,根据参数不同进行不同的操作。不解耦的话就是全部写在一个方法里,很乱。另一个用处就是方便扩展,防止需求三天两头变更带来的麻烦,设计好了以后要增加新的流程直接增加新的类就好了。

下面以计算器为例,展示简单工厂的作用

没有用简单工厂的实例

 <?php
namespace SimpleFactory;

class Bad{
    /**
     * 计算两个数的结果
     * @param $number1
     * @param $operation
     * @param $number2
     * @return float|int|mixed
     */    public function getResult($number1,$operation,$number2){
        switch ($operation){
            case '+':
                $result = $number1 + $number2;
                break;
            case '-':
                $result = $number1 - $number2;
                break;
            case '*':
                $result = $number1 * $number2;
                break;
            case '/':
                if($number2 == 0){
                    throw new \InvalidArgumentException("除数不能为0");
                }
                $result = $number1/$number2;
                break;
            default:
                throw new \InvalidArgumentException("暂不支持此运算");
        }
        return $result;
    }
}

//使用
$bad = new Bad();
$result = $bad->getResult(2,'+',3);
echo $result;
// 5
  

这个例子是个不好的例子,可以看到,所有的功能都在一起,一个方法又在处理流程控制,又在处理业务逻辑,后续需求一旦有改动,像增加流程处理,改动某个流程的逻辑,就只能在这里面改,时间久了,肯定会变得难以维护。

使用简单工厂改写

Operation.php

 <?php
namespace SimpleFactory;

abstract class Operation
{
    /**
     * 左边的数
     * @var numeric
     */    protected $number1;
    /**
     * 右边的数
     * @var numeric
     */    protected $number2;

    /**
     * 计算结果
     * @return mixed
     */    abstract public function getResult();

    /**
     * @param float|int|string $number1
     */    public function setNumber1($number1): void
    {
        $this->number1 = $number1;
    }

    /**
     * @param float|int|string $number2
     */    public function setNumber2($number2): void
    {
        $this->number2 = $number2;
    }

}

  

Add.php

 <?php
namespace SimpleFactory;

/**
 * 加法
 * Class Add
 * @package App\SimpleFactory
 */class Add extends Operation{
    public function getResult()
    {
        return $this->number1 + $this->number2;
    }
}

  

Sub.php

 <?php
namespace SimpleFactory;

/**
 * 减法
 * Class Sub
 * @package App\SimpleFactory
 */class Sub extends Operation{
    /**
     * @return float|int|mixed|string
     */    public function getResult()
    {
        return $this->number1 - $this->number2;
    }
}

  

Mul.php

 <?php
namespace SimpleFactory;


/**
 * 乘法
 * Class Mul
 * @package App\SimpleFactory
 */class Mul extends Operation
{

    /**
     * @inheritDoc
     */    public function getResult()
    {
        return $this->number1 * $this->number2;
    }
}

  

Div.php

 <?php
namespace SimpleFactory;


/**
 * 除法
 * Class Div
 * @package App\SimpleFactory
 */class Div extends Operation
{

    /**
     * @inheritDoc
     */    public function getResult()
    {
       if($this->number2 == 0){
           throw new \InvalidArgumentException('除数不能为0');
       }
       return $this->number1 / $this->number2;
    }
}

  

Factory.php

 <?php
namespace SimpleFactory;

class Factory{

    /**
     * 创建一种运算
     * @param $operation
     * @return Add|Div|Mul|Sub
     */    public function create($operation){
        switch ($operation){
            case '+':
                $result = new Add();
                break;
            case '-':
                $result = new Sub();
                break;
            case '*':
                $result = new Mul();
                break;
            case '/':
                $result = new Div();
                break;
            default:
                throw new \InvalidArgumentException('暂不支持的运算');
        }
        return $result;
    }
}

  

使用
index.php

 <?php
namespace SimpleFactory;
require_once '../Autoload/Autoload.php';

$factory = new Factory();
$operation = $factory->create('+');
$operation->setNumber1(3);
$operation->setNumber2(4);
$result = $operation->getResult();
echo $result.PHP_EOL;

  

实际上就是把原来处理的业务逻辑变成了一个类来处理,流程就变得清爽了。业务逻辑抽象成了一个公共的流程。大家都继承抽象类,只需要实现计算过程就可以了。后续要加新的流程也只需要新增类就好了。

但这个实现也有弊端,就是工厂类里的case如果增加的很多依然看起来很难受,违反了开闭原则。这就需要用到工厂模式了。

文章来源:智云一二三科技

文章标题:php设计模式——简单工厂模式

文章地址:https://www.zhihuclub.com/79195.shtml

关于作者: 智云科技

热门文章

网站地图