PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式


Posted in PHP onApril 09, 2012

思维导图
点击下图,查看大图。

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 介绍
 
 条件逻辑有可能十分复杂,因此本章提供一些重构的手法,专门用来简化它们。
 
全文简述(你可直接跳过下面的内容)

核心重构:Decompose Conditional——分离”转辙逻辑“(switching logic)和”操作细节“(details)分离。

多处测试有相同结果:Consolidate Conditional Expresssion

条件代码中去掉重复成分:Consolidate Duplicate

标识特殊情况:Replace Nested Conditional with Guard Clauses

去除讨厌的控制标记:Remove Control Flag

 
 
 专业术语
 
decompose:分解,分离
consolidate:合并
eligible:合适的,合格的
fragment:碎片,片段
nest:嵌套
guard:保卫
clause:从句
polymorphism:多态
assertion:断言
unchecked exception:不可控异常
 
 Decompose Conditional
 
状况:你有一个复杂的条件(if-else if-else)语句,那么从if、else if、else三个段落中分别提炼出函数。

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 

 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 

 Consolidate Conditional Expression
 
状况:你有一些条件测试,都得到相同的结果,那么将这些测试合并为一个条件式,并将这个条件提炼称为一个独立的函数。
动机: 1、合并后的条件代码会告诉你“实际上只有一次条件检查,只不过有数个并列条件需要检查而已“,——使检查的用意更清晰。

   2、为Extract Method做好准备。——将检查条件提炼成一个独立函数,对于理清代码意义非常有用。它把描述“做什么”的语句换成了“为什么这样做”。

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 

条件语句的“合并理由”也同时指出了“不要合并”的理由:如果你认为你的这些检查的确彼此独立,的确不应该被视为同一次检查,那么就不要使用本项重构。因为在这种情况下,你的代码已经清楚表达出自己的意义。

 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 

 Consolidate Duplicate Conditional Fragments
 
状况:在条件式的每个分支上有着相同的一段代码,那么将这段重复代码搬移到条件之外。
 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 
 Remove Control Flag
 
状况:在一系列布尔表达式中,某个变量带有“控制标记”的作用,那么以break语句或return语句取代控制标记。
 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式
 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 
 Replace Nested Conditional with Guard Clauses
 
状况:函数中的条件逻辑使人很难看清正常的执行路径,那么使用卫语句(Guard Clauses)表现所有特殊情况。

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式


条件式的两种形式:

1、所有分支都属于正常行为:使用[if ... else..]

2、条件式极其罕见:应该单独检查该条件,并在该条件为真时,立刻从函数中返回。——这样的单独检查常常被称为”卫语句“

Replace Nested Conditional with Guard Clauses精髓:给某一分支以特别重视。

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 
 Replace Conditional with Polymorphism
 
状况:你手上有个表达式,它根据对象型别的不同而选择不同的行为,那么将这个条件式的每个分支放进一个subclass内的覆写函数中,然后将原始函数声明为抽象函数。
 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

此代码的坏味道:

1、它太长,当视频有新类型的时候,它会变得更长。

2、它明显做了不止一件事。

3、它违反了单一权责原则,因为它有好几个修改它的理由。

4、它违反了开放闭合原则,因为每当添加新类型时,必须修改它。不过最麻烦的可能是到处皆有类似结构(_get类型名Rank())的函数。

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 Introduce Assertion
 
状况:某一段代码需要对程序状态(state)做出某种假设,那么以断言(assertion)明确表现这种假设。
 

 

 

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

运行结果:

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

运行结果:

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

 
采点:

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

1、常常会有这样的代码,只有当某个条件为真时,该段代码才能正常运行。——实际上程序最后成品往往将assertion统统删除。

2、这样的假设通常并没有在代码中明确表现出来,你必须阅读整个算法才能看出。——有时候程序员会以注释写出这样的假设,而assetion是一种更好的技术。

3、assertion是一个条件式,应该总是为真。如果失败,表示程序员犯了错误

4、assertion可以作为交流与调试的辅助。——交流:可以帮助程序员阅读理解代码所做的假设。调试:帮助程序员找到bug,可以在距离最近的地方抓住bug。

5、assertion并不改变程序的任何行为。

6、assertion价值:帮助程序员理解代码正确运行的必要条件。

7、建议最好把assertion的条件式使用Extract Method,为了将若干地方的重复码提炼到同一个函数中,也许只是为了更清楚说明条件式的用途。

 
 总结
 
       这一章我比较喜欢“Replace Nested Conditional with Guard Clauses “这个方式,我在平时的代码中也经常这样用,还有人给这种方式取名叫”卫从句“。
      还有一个就是我经常在php开发中用的调试是var_dump()或print_r(),我也第一次发现php中还有assert这种方式,不错!
 
        在学习和实践的过程中,我也学到了很多不错的方式。但是我觉得在团队开发中,有的时候还是”大局为重“,按照团队的习惯方式去编码,或者你可以跟团队沟通,得到大家的认可之后,在使用这里面的方法,这样大家彼此调试和阅读对方代码的时候比较方便。
PHP 相关文章推荐
中篇:安装及配置PHP
Dec 13 PHP
php xml 入门学习资料
Jan 01 PHP
php中explode与split的区别介绍
Oct 03 PHP
一个简单的php加密解密函数(动态加密)
Jun 19 PHP
深入Nginx + PHP 缓存详解
Jul 11 PHP
php中sql注入漏洞示例 sql注入漏洞修复
Jan 24 PHP
php操作mysql数据库的基本类代码
Feb 25 PHP
ECSHOP完美解决Deprecated: preg_replace()报错的问题
May 17 PHP
thinkphp多表查询两表有重复相同字段的完美解决方法
Sep 22 PHP
详解PHP中foreach的用法和实例
Oct 25 PHP
购物车实现的几种方式优缺点对比
May 02 PHP
Thinkphp5.0框架视图view的模板布局用法分析
Oct 12 PHP
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
Apr 09 #PHP
PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数
Apr 09 #PHP
PHP乱码问题,UTF-8乱码常见问题小结
Apr 09 #PHP
PHP中return 和 exit 、break和contiue 区别与用法
Apr 09 #PHP
php 的加密函数 md5,crypt,base64_encode 等使用介绍
Apr 09 #PHP
PHP压缩html网页代码(清除空格,换行符,制表符,注释标记)
Apr 02 #PHP
PHP文件注释标记及规范小结
Apr 01 #PHP
You might like
php获取某个目录大小的代码
2008/09/10 PHP
PHP大小写问题:函数名和类名不区分,变量名区分
2013/06/17 PHP
使用PHP强制下载PDF文件示例
2014/01/17 PHP
laravel5.2实现区分前后台用户登录的方法
2017/01/11 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
thinkPHP5框架闭包函数与子查询传参用法示例
2018/08/02 PHP
php文件上传原理与实现方法详解
2019/12/20 PHP
js 函数的执行环境和作用域链的深入解析
2009/11/01 Javascript
深入理解JavaScript系列(6) 强大的原型和原型链
2012/01/15 Javascript
jQuery Mobile 导航栏代码
2013/11/01 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
浅析JavaScript访问对象属性和方法及区别
2015/11/16 Javascript
jQuery实现监控页面所有ajax请求的方法
2015/12/10 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
2016/11/30 Javascript
深入理解angular2启动项目步骤
2017/07/15 Javascript
详解Vue学习笔记进阶篇之列表过渡及其他
2017/07/17 Javascript
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
2017/10/16 Javascript
react实现一个优雅的图片占位模块组件详解
2017/10/30 Javascript
vue.js使用3DES加密的方法示例
2018/05/18 Javascript
MVVM 双向绑定的实现代码
2018/06/21 Javascript
[56:58]VP vs Optic 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python中使用第三方库xlutils来追加写入Excel文件示例
2015/04/05 Python
python删除过期文件的方法
2015/05/29 Python
简单掌握Python中glob模块查找文件路径的用法
2016/07/05 Python
pandas 实现将重复表格去重,并重新转换为表格的方法
2018/04/18 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
Python 正则表达式 re.match/re.search/re.sub的使用解析
2019/07/22 Python
正则给header的冒号两边参数添加单引号(Python请求用)
2019/08/09 Python
Opencv+Python识别PCB板图片的步骤
2021/01/07 Python
倡议书格式
2014/08/30 职场文书
机关干部个人对照检查材料思想汇报
2014/09/28 职场文书
安全生产工作汇报
2014/10/28 职场文书
门市房租房协议书
2014/12/04 职场文书
2015年毕业生实习评语
2015/03/25 职场文书
义卖募捐活动总结
2015/05/09 职场文书
2019年妇科护士的自我鉴定(3篇)
2019/09/26 职场文书