php设计模式之工厂模式(工厂模式实现计算器功能)

php设计模式之工厂模式(工厂模式实现计算器功能)

因为工作的需要,陆陆续续接触了很不多不同的框架,也慢慢渗透了一些设计模式。
当初选择入手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,我要不断学习,并且在其中找到快乐,我才会在这条坑上越陷越深!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值