因为工作的需要,陆陆续续接触了很不多不同的框架,也慢慢渗透了一些设计模式。
当初选择入手php,就是因为脚本语言,简单易学。正因为是脚本语言很多人拿着php做着面对过程的事情。在工作中我维护过一个function写了1000行的代码,还要一行一行下来开始寻找bug。当时我就想设计模式所带来的好处。
简单的抽象成生活的一个例子就是,你需要一双鞋子,但是你不用关心鞋子的构造,采用什么布料,怎么制作。这时候你就需要告诉制造鞋子工厂说 我需要一双运动鞋。
你 > client 发送请求
鞋子工厂 > factory 接受请求 再返回一双鞋给用户
我们现在要用php实现一个计算器的功能,具有加减乘除的功能,很多刚学php或者刚毕业的应届生一看到这就乐了,这不是很简单吗,一个php脚本几行代码就能搞定的东西。
//主程序代码
$parmasFirst = 1;
$parmasSecond = 2;
$operator = '/';
$result = 0;
switch($operator){
case '+': $result = $parmasFirst + $parmasSecond ;break;
case '-': $result = $parmasFirst - $parmasSecond ;break;
case '*': $result = $parmasFirst * $parmasSecond ;break;
case '/': {
if (empty($parmasSecond)) {
throw new Exception('error parms ');
}
$result = $parmasFirst / $parmasSecond;
break;
}
default:throw new Exception('error operator');
}
echo $result;
我们在设想一下,随着计算器的不断升级,不断有开平方、立方根……的复杂算法,你该怎么去维护代码?
你们会想 不就是在switch继续加分支。我们假设如果业务不断的扩展一个,功能被扩充了几千行代码的switch,你该怎么去维护?
第一种方法就是对switch里面的代码进行封装
switch($operator)
{
case '+':
{
$operatorAddObj = new OperatorAdd($parmasFirst,$parmasSecond);
$result = $operatorAddObj->getResult();
break;
}
case '-':
{
$operatorAddObj = new OperatorSub($parmasFirst,$parmasSecond);
$result = $operatorAddObj->getResult();
break;
}
case '*':
{
$operatorAddObj = new OperatorMul($parmasFirst,$parmasSecond);
$result = $operatorAddObj->getResult();
break;
}
case '/':
{
$operatorAddObj = new OperatorDiv($parmasFirst,$parmasSecond);
$result = $operatorAddObj->getResult();
break;
}
default:throw new Exception('error operator');
}
abstract class Operator
{
protected $a,$b;
public function __construct($parmasFirst,$parmasSecond)
{
$this->a = $parmasFirst;
$this->b = $parmasSecond;
}
abstract function getResult();
}
class OperatorAdd extends Operator
{
public function getResult()
{
return $this->a + $this->b;
}
}
class OperatorSub extends Operator
{
public function getResult()
{
return $this->a - $this->b;
}
}
class OperatorMul extends Operator
{
public function getResult()
{
return $this->a * $this->b;
}
}
class OperatorDiv extends Operator
{
public function getResult()
{
if(empty($this->b)) {
throw new Exception('error parms b=0');
}
return $this->a / $this->b;
}
}
但是你还是没有脱离switch这个架构。现在很多php框架都倡导模块化的设计理念,我们需要对不同的运算算法封装成独立一个模块,而不是通过switch不断去扩充,我们添加功能也不会去修改 主程序代码,以便带来不必要的问题bug.
我们稍微把主程序的代码的swith进行修改
//主程序代码
$parmasFirst = 1;
$parmasSecond = 1;
$operator = '/';
$result = 0;
$result = OperatorFactory::create($parmasFirst,$parmasSecond,$operator)->getResult();
echo $result;
class OperatorFactory
{
public static $operator = array(
'*' => 'add',
'/' => 'div',
'-' => 'sub',
'+' => 'add'
);
public static function create($a,$b,$operator)
{
if(!array_key_exists(strtolower($operator),self::$operator)) {
throw new Exception('no operator');
}
$operatorName = self::$operator[$operator];
$operatorObj = 'Operator' . ucfirst($operatorName);
if(!class_exists($operatorObj)) {
throw new Exception('no class');
}
return new $operatorObj($a,$b);
}
}
这样有个好处就是 你去修改 其中一个算法的时候,不会去破坏其他算法的内部结构,而且你新增一个算法也很方便,也不用去更改主程序代码,只要稍微修改工厂模式就可以。便于代码维护
之后不断更新不同的设计模式来实现不同的案例和应用场景。 我已经给自己定好了目标了! 做一名phper,我要不断学习,并且在其中找到快乐,我才会在这条坑上越陷越深!