【《重构 改善既有代码的设计》学习笔记3】代码的坏味道[通俗易懂]

【《重构 改善既有代码的设计》学习笔记3】代码的坏味道本篇文章的内容来自《重构 改善既有代码的设计》一书学习笔记整理并且加上自己的浅显的思考总结!知道重构的原则和何时进行重构,那本篇就总结一些代码的坏味道,知道具体从哪些方面来进行重构。kent Beck提出用 味道来形容重构的时机。作者说:何时必须重构没有一个精确的衡量标准,任何量度规矩也比不上一个见识广博者的直觉。如果没有广博的见识…

大家好,又见面了,我是全栈君。

【《重构 改善既有代码的设计学习笔记3】代码的坏味道

本篇文章的内容来自《重构 改善既有代码的设计》一书学习笔记整理并且加上自己的浅显的思考总结!

知道重构的原则和何时进行重构,那本篇就总结一些代码的坏味道,知道具体从哪些方面来进行重构。

kent Beck提出用 味道来形容重构的时机。

作者说何时必须重构没有一个精确的衡量标准,任何量度规矩也比不上一个见识广博者的直觉如果没有广博的见识,也可以通过一些迹象来发现这里有一个可以用重构来解决的问题。

在不断的学习和成长中,我们必须要学会 培养自己的判断力和“嗅出代码坏味道”的本领。

下面会列出一些“坏味道的条款”,愿他们能够为你指引正确的方向。

代码坏味道

1、 重复代码(Duplicated Code)

坏味道行列中 “带头大哥” 就是 重复代码。如果在一个以上的地方/看到相同的程序结构,那么可以肯定 : 设法将他们合二为一,程序会变得更好。

最单纯代码重复 是 同一个类的两个函数有相同的表达式。 说白一点就是两段代码一模一样。 此时可以采用 **提取方法(Extract Method)**的方法提炼重复的代码。 在其他地方统一的调用提炼出来的那一段代码。【现在IDEA这个工具有代码重复检查功能,如果两段代码重复会给出提示,如果在开发遇到重复提示,不要绕过去,视而不见。我认为应该想着看如何去优化

另一种常见的情况: 两个互为兄弟的子类内含相同表达式。这种情况下也可以使用 提取方法(Extract Method),将提炼出的代码推到 超类内。

【不管什么方式的代码重复。最主要的是进行提炼,确保重复的代码只有一套】

2、过长函数(Long Method)

拥有短函数的对象会活得比较好,比较长。不熟悉面向对象中,常常觉得对象程序有无穷无尽的委托,根本没有进行任何计算。接触时间长后,你就会发现这些小小函数有多大的价值。

“间接层” 所能带来的全部利益—解释能力、共享能力、选择能力,都是小型函数支持的。

程序越长越难理解,这已经成为程序员的共识。

在当前的实际开发中,你应该更积极地分解函数,并且给分解好的小函数起一个好名字,让第二阅读者可以直接通过函数名字能够知道函数的作用,而不必去看其写了什么。

在很多场合中,把函数变小只需要只用提取方法(Extract Method),找到函数中集合在一起的部分,提炼一个新函数。

如何去确定该提炼哪一段代码呢?一个很好的技巧是: 寻找注释。 它们通常能指出 代码用途和实现手法之间的语义距离。条件表达式和循环常常也是提炼的信号。

【一般尽量一个函数的代码函数控制在几十行内,太长了就要想着进行拆分】

3、过大的类(Large Class)

如果想利用单个类做太多的事情,就往往会出现太多的实例变量。 一旦如此,重复代码 也就接踵而至了。

【在项目中见到过,在实体类中写了大量的业务代码,看起来真是痛苦!】

4、过长参数列(Long Parameter List)

刚开始学习编程的时候,老师教过:把所有的函数所需要的东西都以参数传递过去。

【但是所有的东西都是一个balance,过度了就不好了】

太长的参数列难以理解,并且很多时候会造成参数前后传递不一致,不易使用,而且一旦你需要添加或者删除参数,那么整个方法就不得不进行修改。这样代码在维护起来也不少很方便。

所以如果在代码中遇到过长的参数传递,一定要进行优化和重构。

【我这边建议是如果是参数传递较多,一个是可以使用Map进行封装,二是定义对象进行参数传递。】

5、发散式变化(Divergent Change)

如果某个类经常因为不同的原因在不同的方向上发生变化, 发散式变化就出现了。当你看着一个类说: 如果新加入一个数据库,我必须要修改 这三个函数;如果新出现一个金融工具,我必修这四个函数。 那么此时也许将这个对象分成两个会更好,这样一来每个对象就可以只因一种变化而需要修改。

【这种味道很难嗅出来,不过一旦有类似味道,就要注意了】

6、散弹式修改(Shotgun Surgery)

当遇到某种变化,你都必须在许多不同的类内做出需要小修改。 散弹式修改: 一种变化引发多个类相应修改。

【举个简单的例子:】如下伪代码

// state : 1 开启 ,0 关闭
Class1{ 
   
    if(state == 1){ 
   
        // do something
    }    
}

Class2{ 
   
    if(state == 1){ 
   
        // do something
    }    
}



想类似代码,如果状态state的标识修改了,那么涉及的代码都要做更改

7、依恋情结(Feature Envy)

对象技术的全部要点在于:这是一种“将数据和数据的操作行为包装在一起”的技术。

有一种经典的气味:函数对某个类的兴趣高过自己所处类的兴趣。

疗法:把这个函数移到另一个地方,移动到它该去的地方。先使用 提炼函数(Extract Method) ,在使用 移动函数(Move Method)

这种依赖并非所有的情况都是这么简单。一个函数往往会用到几个类的功能,那么它究竟该被置身何处?

原则:判断哪个类拥有最多此函数使用的数据,然后就把这个函数和那些数据摆放在一起、

【这种功力还是需要锻炼,有时候没有那么直接可以一眼看出】

8、Swtich 现身(Switch Statements)

面向对象程序一个最明显的特征就是:少用swtich(或case)语句。

从本质上说:switch 语句问题在于重复。

解决: 可以使用多态来优雅解决此问题。(如可以参考案例1中的代码)

总结

代码的坏味道书中列举了很多,先就总结上面这么多,也是一些平时在写代码经常会遇到的。

如果想了解更多推荐你阅读书籍。

有时候少就是多,每天不要强求掌握太多,相信积累的力量。 重构是一条要走很长的路,掌握重构思想,精进代码质量!


如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到,谢谢!

如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客和关注的个人微信公众号!

愿你我在人生的路上能都变成最好的自己,能够成为一个独挡一面的人。

【《重构 改善既有代码的设计》学习笔记3】代码的坏味道[通俗易懂]

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

博客首页 : http://blog.csdn.net/u010648555

© 每天都在变得更好的阿飞

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/121052.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 职称计算机考试模块教程怎么用,如何巧妙的选择职称计算机考试模块?

    职称计算机考试模块教程怎么用,如何巧妙的选择职称计算机考试模块?【摘要】环球网校分享的如何巧妙的选择职称计算机考试模块?希望对大家备考有帮助,更多资料敬请关注环球职称计算机考试频道,网校会及时更新考试资料…… 相关推荐:全国2016年职称计算机考试报名时间汇总【摘要】环球网校分享的“如何巧妙的选择职称计算机考试模块?”希望对大家备考有帮助,更多资料敬请关注环球职称计算机考试频道,网校会及时更新考试资料……职称计算机考试,根据学习内容划分了十四类共25个模块,评…

  • 深度学习(五)学习率的调节

    深度学习(五)学习率的调节   学习率对于深度学习是一个重要的超参数,它控制着基于损失梯度调整神经网络权值的速度,大多数优化算法(SGD、RMSprop、Adam)对其都有所涉及。学习率越小,损失梯度下降的速度越慢,收敛的时间更长,如公式所示:new_weight=existing_weight—learning_rate*gradient(新权值=当前权值–学习率×梯度)    如果学习…

  • getline(cin,str)与cin.getline(str)的区别 ,hd1062单词逆转

    getline(cin,str)与cin.getline(str)的区别 ,hd1062单词逆转

  • css实现导航菜单下拉效果「建议收藏」

    css实现导航菜单下拉效果「建议收藏」通过css也可以实现简单的导航栏效果,一些不会写js的下伙伴不用担心了。先上HTML部分<nav><ulclass="level"><li><ahref="">首页</a></li><li>

  • 数学建模算法学习——各类模型算法汇总[通俗易懂]

    数学建模算法学习——各类模型算法汇总[通俗易懂]相关模型解决的问题数据分析类算法一览100个经典动态规划方程优化问题线性规划简介:线性规划的目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以是小于号也可以是大于号。为了避免这种形式多样性带来的不便,Matlab中规定线性规划的标准形式为其中c和x为n维列向量,A、Aeq为适当维数的矩阵,b、beq为适当维数的列向量。代码实现…

  • 【转载】lvs为何不能完全替代DNS轮询

    【转载】lvs为何不能完全替代DNS轮询

    2021年11月20日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号