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如果增加的很多依然看起来很难受,违反了开闭原则。这就需要用到工厂模式了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值