博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式】一:简单工厂模式
阅读量:5224 次
发布时间:2019-06-14

本文共 4558 字,大约阅读时间需要 15 分钟。

此系列文章为阅读大话设计模式书籍记录的笔记

使用简单工厂模式,利用面向对象的三大特性-【封装】-【继承】-【多态】实现一段计算器代码。下面示例为逐步优化,也可认为是一个初级程序员慢慢优化自己代码的过程。

 

一:面向过程思想的实现形式

jisuan(1, 2, '/');echo $res;// 此种写法的缺点:不易扩展,没有按业务进行封装,没办法复用// 改进一步,将两个业务逻辑进行封装,可复用的内容进行提炼, 例如计算器分为输入端和计算端

 

二:使用封装,按照功能模块进行划分,这样较前一种书写形式已经比较好修改代码,寻找功能块了,但是还是很渣

getResult($num1, $num2, $operation); echo $res; }}$a = new Operation();$a->Main(1, 2, '/');// 这仅仅是使用到了面向对象的三个特性,封装,继承,多态中的一个,封装,但是此时耦合度很高,好的程序要做到松耦合,就是修改一个地方,// 并不会影响到现有的功能,如果此处想增加一个开方根运算,紧耦合中必须得更改源代码,松耦合中,新增新的功能不会影响到旧的,所以使用继承的特性

 

三:上述方法已经使用了封装,但是还是不利于扩展;

  如果产品经理说我需要加计算平法的功能进去,那只能是修改switch的功能块,此处因为逻辑简单,可能认为修改会简单些;

  但是如果每个计算规则中都需要记录用户的输入信息,存入数据库,存入redis, 然后用一次计算器给加个积分,积分到了哪个级别自动发放礼品等等复杂逻辑进去。

  那我心里就会骂这产品瞎改什么需求,当然产品经常改需求很不好,但也有咱们自己的原因,代码写成一大坨,耦合性这么高,找个大牛出来都觉得看的头疼,别说咱们这种渣渣了;

  所以此处我们可以想办法把各个运算规则再拆出来,再封装啊。

  如果使用面向过程的思想,可以将各个规则分别封装成一个方法,然后用的时候调用就可以了,当然这种也能满足上面描述的情况;

  但是如果这些计算规则都具有一定的共性,那么此处使用面向对象的继承更优一些

$name = $value; } public function __get($name) { return $this->$name; } public function getResult() { $res = 0; return $res; }}// 创建加法类class OperationAdd extends Operation{ // 重写getResult方法 public function getResult() { $res = 0; $res = $this->num1 + $this->num2; return $res; }}// 创建减法类class OperationSub extends Operation{ public function getResult() { $res = 0; $res = $this->num1 - $this->num2; return $res; }}// 创建乘法类class OperationMul extends Operation{ public function getResult() { $res = 0; $res = $this->num1 * $this->num2; return $res; }}// 创建除法类class OperationDiv extends Operation{ public function getResult() { if ($this->num2 == 0) { return 'error'; } $res = 0; $res = $this->num1 - $this->num2; return $res; }}$add = new OperationAdd();$add->num1 = 1;$add->num2 = 2;$res = $add->getResult();echo $res;// 此时已经利用面向对象的继承特性,将程序的扩展性能体现出来,如果需要新增一个计算平方的方法,只需要再新增一个类,然后继承自基类就好// 而且并不会影响原有的计算程序, 但是此时存在一个问题,我们需要自己去判断实例化哪个类,那么就需要一个方法去帮我们调度,那此时就可以// 使用第一个设计模式,简单工厂模式,到时候这个方法负责帮我们调度,我们只需将对应参数给其即可

 

四: 上边使用了,封装,继承,代码已经较为清晰了,如果产品让我加一个计算平方的,那我加上这一个类就好了啊,新加的这个类中只需要写与平方功能有关的代码就行了;

  但是此处是我们手动的去调用计算规则的,这样是具有问题的,那就引申出第一个设计模式,简单工厂模式;

  说白了,就是建一个类,我们只需要按照规则将参数传进去,这个工厂类自动判断实例化哪个类去,我只关心结果。使用简单工厂模式后,封装性更好了,使用者无需关注内部怎么实现的,

  只需要按照指定规则调用就好了,如果想自己扩展,代码结果也很清晰

 

$name = $value; } public function __get($name) { return $this->$name; } public function getResult() { $res = 0; return $res; }}// 创建加法类class OperationAdd extends Operation{ // 重写getResult方法 public function getResult() { $res = 0; $res = $this->num1 + $this->num2; return $res; }}// 创建减法类class OperationSub extends Operation{ public function getResult() { $res = 0; $res = $this->num1 - $this->num2; return $res; }}// 创建乘法类class OperationMul extends Operation{ public function getResult() { $res = 0; $res = $this->num1 * $this->num2; return $res; }}// 创建除法类class OperationDiv extends Operation{ public function getResult() { if ($this->num2 == 0) { return 'error'; } $res = 0; $res = $this->num1 - $this->num2; return $res; }}// 创建一个工厂类,帮助我们调度程序class OperationFactory{ // 参数检测,调度创建工厂 public function getOperaRes($num1, $num2, $operation) { if (!is_numeric($num1) || !is_numeric($num2)) { return 'num must int'; } if (!$operation) { return 'method must'; } // 调用工厂,工厂生成了模型 $opera = $this->createOperation($operation); $opera->num1 = $num1; $opera->num2 = $num2; $res = $opera->getResult(); return $res; } public function createOperation($operation) { $opera = null; // 简单判断参数 switch ($operation) { case '+': $opera = new OperationAdd(); break; case '-': $opera = new OperationSub(); break; case '*': $opera = new OperationMul(); break; case '/': $opera = new OperationDiv(); break; default: return 'error'; } return $opera; }}$opera = new OperationFactory();$res = $opera->getOperaRes(1, 3, '+');echo $res;// 此处主要体现简单工厂模式的思想,此类还有很多地方需要完善,当然这只是简单的加减乘除,不用工厂模式更加简单,但是计算规则复杂后就体现出封装// 的优越性,产品经理需求变动频繁,经常加功能,该功能就体现出了继承导致松耦合的优越性

 

转载于:https://www.cnblogs.com/rcltocode/p/10530443.html

你可能感兴趣的文章
Fragment
查看>>
比较安全的获取站点更目录
查看>>
苹果开发者账号那些事儿(二)
查看>>
5.0以上机器XPOSED框架安装流程
查看>>
((完美有效))安卓神器XPOSED框架不用root安装指南
查看>>
Java删除properties配置文件中指定键值的代码
查看>>
python使用chardet判断字符串编码,超简单的代码
查看>>
红米手机使用应用沙盒动态修改硬件信息
查看>>
vivo手机使用应用沙盒一键修改屏幕数据
查看>>
[NOIP2012TG] 洛谷 P1080 国王游戏
查看>>
7、字符串拼接避免值类型装箱!
查看>>
js 极简获取表单 元素 !
查看>>
追踪方法上的特性!
查看>>
使用C#交互快速生成代码!
查看>>
洛谷P4315 月下“毛景树” 边权树剖+双标记
查看>>
P2234 [HNOI2002]营业额统计
查看>>
UVA11374 Airport Express
查看>>
P1373 小a和uim之大逃离 四维dp,维护差值
查看>>
P2146 [NOI2015]软件包管理器
查看>>
NOIP2015 运输计划 树上差分+树剖
查看>>