侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数

php  /  管理员 发布于 7年前   245

思维导图 点击下图,可以看大图。
介绍

我把我比较喜欢的和比较关注的地方写下来和大家分享。上次我写了篇《php 跟老大的对话》。还是有很多疑问,这书帮了我不少的忙。

如果你比较繁忙,或者懒得看文字,建议你直接看截图,也会有很大的收获的。你可以通过比较截图中的代码就能知道孰优孰劣了。

代码部分我为什么用图呢?因为我经常用手机看代码,博客园的代码在手机里乱七八糟的,还是看图比较舒服。

专业术语

我们毕竟是用英文字母编码,所以用一些英语单词,更能显示出我们的专业性。以下的英文单词,你如果掌握了,与其他coder交流的时候会更直接,更专业。――臭显摆一下吧,呵呵。
“*”表示文中经常提到的

inline:内联
function:函数
*method:方法
finely grained:细粒度的
rename:重命名
query:查询
temp:临时(temporary)――一般指临时变量
*extract:提取――我个人更喜欢翻译成“提炼”
*duplicate:复制
split:剖解
variable:变量
factor:因素,因子

重构原则

一、何谓重构?
  名词形式:对软件内部结构的一种调整,目的是在不改变软件之可察行为前提下,提高其可理解型性,降低其修改成本。
  动词形式:使用一系列重构准则,在不改变软件之可察行为前提下,调整其结构。

二、为何重构 ?
  1、经常重构可以让代码维持该有的形态。
  2、让代码找到合适的位置。
  3、让软件更易理解。
  4、可以找到bug。
  5、提高我们的编码速度。
三、重构的难题
  1、修改接口命名
    如果你的类中的方法是public,那么你在rename的时候,冒着很大的风险,你不知道到底有哪些模块在调用你的这个方法(我们经常的做法是在整个项目下做grep操作,然后逐一看各个模块的调用和逻辑)。――所以我们在编写类的时候不管是属性还是方法尽量做到private,避免接口开放。

  2、何时不该重构
    (1)重写所有代码,而且现有代码实在太混乱,重构还不如重写。
    (2)项目临近结束的时候,应该避免重构。我们可以把重构放到二期去解决。

代码的坏味道

一、Duplicate Code
  1、同一个类,两个方法含有相同表达式。
    解决方法:你可以Extract Method提炼重复代码,然后让这两个方法都调用这个Extract Method。
2、两个类,有相似的方法。
    解决方法:(1)把两个类的方法提出来,共同构造一个父类。
         (2)把其中一个类的方法删除,调用另一个类的方法。
二、Long Method
  1、短函数:代码阅读费点力气,因为我们必须经常转换上下文去看看子程序做了什么。但是让small method容易理解的真正关键在于一个好的名字。读者可以通过名字了解函数的作用,根本不必去看其中写了些什么。――早期的编程语言中,调用方法需要额外开销,这使得coder不愿意使用small method。但是现代的OO语言几乎已经完全免除了process内的额外开销(函数调用)。

  2、注释地方提炼信号:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以其用途命名。可以对一组或甚至短短一行代码做这件事。――只要函数名称能够解释其用户,我们也该毫不犹豫地那么做。

"函数"理解为”做什么“或”如何做“

  3、条件式和循环常常也是提炼信号。

  4、《代码整洁之道》的一个例子。我们可以想想!

三、Large Class

  1、Class内数个属性变量有相同前缀或者字尾,可使用Extract Class。

  2、Class内并非大多数变量使用属性变量,可使用Extract Class。
  
  3、有太多代码,可Extract Class。

四、Long Parameter
  做成Introduce Parameter Object。――这个我不太赞同,因为我在使用别人方法的时候,我很少去看代码实践,更不要说去看里面都用到了对象的那些属性或者方法,取我想要的数据了。

五、Switch Statements
  1、少用switch语句。――问题在于duplication。添加新case的时候,你必须找到所有case并修改它们。
  
  2、用多态来替换它。做法:1.将switch进行Extract Method;2.MoveMethod把case里的实践代码放到多态性的class里。

六、 Comments
  试试用Extract Method,如果还不行,那你试试Rename Method。

当你感觉需要撰写注释,请先尝试重构,试着让所有注释变得多余。

  注释一般用于将来的打算,还可以用于你并无十足把握的区域(为什么做某事)。


重新组织你的函数

  Long Method往往包含太多信息,这些信息又被错综复杂的逻辑掩盖,不易鉴别。

一、Extract Method

状况:我看见一个过长的函数或者需要一段注释才能让人理解用途的代码,那么将这段代码放进一个独立函数中,并让函数名称解释改函数的用途。

 

动机:

简短而有良好命名的函数:――finely grained

  1、复用机会大。

  2、函数读起来像读一系列comments。

  3、函数覆写容易。

重点:函数长度关键在于函数名称和函数本体之间的语义距离。如果提炼动作可以强化代码的清晰度,那么就去做。

作法:

  1、创建新函数,根据函数的意图命名――以它“做什么”命名,而不是以它“怎样做”命名。

    =》 即使Extract Function 非常简单,例如只是消息或函数调用,只要新Function能够以更好方式昭示代码意图,你也应该提炼它。但如果你想不出更有意义的名称,就别动它。

  2、将Extract的代码从Source Function 中Move到New Function中。

二、Inline Method

  Method Body与Method Name一样清晰易懂的时候,请Inline Method。

 

三、Inline Temp

一个临时变量,只被一个简单表达式赋值一次,而且赋值完也只使用了一次。――请Inline Temp

 

四、Replace Temp with Query

如果一个Temp变量,保存一个表达式,将这个表达式Extract Method。――这就是所谓的查询式,query

 

动机:

  1、局部变量会使代码难以提炼。

  2、临时变量会驱使你写出更长的代码。如果改成query method,那么class下的method,都可以获得这份信息。――将编写出更清晰的代码。

  3、Replace Temp with Query往往是你运用Extract Method之前必不可少的步骤。

作法:

  1、找出只被赋值一次的临时变量。

    =>  如果临时变量赋值超过一次,考虑使用Split Temporary Variable将它分割成多个变量。

  2、对Temp Variable赋值的右侧部分,Extract到一个独立函数中。

           =>  将Method声明为private,日后如果有其他class用的时候再放开它(public或protected)。

  

如果代码组织良好,那么你往往能发现更有效的优化方案。――――如果性能真的很糟糕,那么放回去也很容易。 五、Introduce Explaining Variable 将复杂表达式中(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途。 

 动机:  表达式复杂而且难以阅读。在这种情况下,临时变量可以帮助你将表达式分解为比较容易管理的形式。   六、Split Temporator Variable  某个临时变量被赋值超过一次,它既不是循环变量,也不是集合变量。那么针对每次赋值,创造一个独立的,对应的临时变量。

 

 

动机:

  1、如果临时变量承担多个责任,它就应该被替换为多个临时变量。每个变量只承担一个责任。

  2、同一个临时变量承担两件不同的事情,会令review变得糊涂。

六、Remove Assignments To Parameters如果你的代码对参数进行赋值,那么以一个临时变量取代该参数的位置。 

 

七、Replace Method with Method Object

大型函数对局部变量的使用无法采用Extract Method。那么将这个Method放进一个单独对象中,如此一来,让局部变量成为对象的filed,然后在同一个对象中将大型函数分解为数个小型Method。

 

 

动机:

  1、将相对独立的代码从大型Method中Extract出来,就可以大大提高代码的可读性。

  2、一个Method中,局部变量泛滥成灾,分解这个函数将会非常困难。

  3、Replace Method with Method Object 会将所有局部变量变成对象的值域。然后对这个新对象进行Extract Method了。

八、Substitute Algorithm 如果你想把某个算法替换为另一个更清晰的算法,那么将Method Body替换为另一个算法。――就是直接修改原来的Method Body。 动机:随着对问题有了更多的了解,你发现一件事可以有更清晰的方式,就应该以较清晰的方式取代复杂方式。

总结

这只是本书的一部分内容,我知道会有很多的coder应该有不同的观点,我自己也是,有的很赞同,有的我也是不太赞同的。所以要“则其善之而从之,其不善之而改之”。

欢迎大家发表下自己的看法。

您可能感兴趣的文章:

  • 五款PHP代码重构工具推荐
  • PHP代码维护,重构变困难的4种原因分析
  • PHP 杂谈《重构-改善既有代码的设计》之五 简化函数调用
  • PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式
  • PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
  • PHP 杂谈《重构-改善既有代码的设计》之二 对象之间搬移特性
  • rephactor 优秀的PHP的重构工具
  • PHP代码重构方法漫谈


  • 上一条:
    PHP 杂谈《重构-改善既有代码的设计》之二 对象之间搬移特性
    下一条:
    PHP乱码问题,UTF-8乱码常见问题小结
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客