php抽象工厂模式设计,php设计模式简单工厂模式
php抽象工厂模式设计,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 Sub * @package App\SimpleFactory */ class Sub extends Operation{ /**
简单工厂是什么?简单工厂是由三部分组成:- 1个工厂类
- 1个接口类或抽象类
- 多个具体实现
- 接口或抽象类定义待开发功能的整体结构,需要哪些实现
- 多个具体实现继承接口或抽象类具体实现功能。
- 简单工厂来创建具体实现的实例进行调用
关系图:
最常用的就是用于流程控制解耦,比如输入一个参数,根据参数不同进行不同的操作。不解耦的话就是全部写在一个方法里,很乱。另一个用处就是方便扩展,防止需求三天两头变更带来的麻烦,设计好了以后要增加新的流程直接增加新的类就好了。
下面以计算器为例,展示简单工厂的作用
没有用简单工厂的实例<?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如果增加的很多依然看起来很难受,违反了开闭原则。这就需要用到工厂模式了。