由学习《软件设计重构》所想到的代码review(一)
前言
对于一个程序猿来讲怎样来最直接的来衡量他的技术能力和产出呢?我想最直观的作法是看他的代码编写能力,就拿我常常接触的一些程序猿来看,他们买了非常多技术重构类书籍。可是看完后代码编写能力并没有显著提高。有人说可以用代码review工具啊,可是像市面上的这些代码review工具。仅仅能帮助我们解决表面的bug和规范点。还无法帮助我们发现更深层次的设计问题。
以下我将结合《软件设计重构》这本书谈谈在进行代码review的时候。须要关注的哪些点。
一、技术债务
何为技术债务?
技术债务是有意或无意的做出错误的或非最优的设计决策所引发的俩务
我们在代码review的时候。常常碰到一些实现有瑕疵的方案。然后对方说由于时间太紧急暂时採用的方案,等第二期项目将其完好,于是往往第二期以后这个暂时方案就非常难再去触动了,时间越长代码冗余越大,越难去做改动。于是这就是典型的技术债务。债务越积越多,最后仅仅能又一次彻底重构项目才干解决这个问题,这也叫做技术破产。
于是我们的做法有一个债务管理系统,在代码review的时候。会将这些债务或者暂时方案录入到系统中并制订偿还日期,那么兴许债务顺利偿还后。更改系统状态。否遭遇一直没有偿还的。系统将以邮件的方式提醒,债务累积到一种数目后将与绩效挂钩考核。
二、设计的坏味道
前面仅仅是从债务的角度说明了所带来的危害。事实上引起技术债务的一个非常重要的原因是对设计坏味和重构认识不足。
我们从设计的角度来看代码时,要遵循六要素:
- 可理解性
代码理解起来的难易程度 - 可改动性
在改动既有功能时,不会导致连锁反应。 - 可扩展性
支持新功能,不会导致连锁反应 - 可重用性
可以在代码的其它地方引用其一块代码 - 可測试性
项目要可以支持单元測试 - 可靠性
在正确的实现了功能的同一时候,也可以考虑各种异常情况怎样容错
2.1、设计坏味的分类
2.1.1 抽象型坏味道
1、缺失抽象
举例说明:
* 问题点:
在JDK1.0中方法printStackTrace()
以字符串的方式将栈跟踪打印到标准错误流:
public class Throwabe {
public void printStackTrace();
}
在须要以编程方式訪问栈跟踪元素的客户程序中,必须要编程代码来获取数据,如行号等,由于客户程度依赖这样的字符串格式。JDK设计人员仅仅能在兴许版本号中兼容这样的格式了。
- 解决方法
public class Throwabe {
public void printStackTrace();
public StackTraceElement[] getStackTrace();
}
从Jdk1.4起对JAVA的API进行了改进,StackTraceElement类就是原来设计中缺失的对象,定义例如以下:
public final class StackTraceElement {
public String getFilename();
public int getLineNumber();
public String getClassname();
......
}
2、命令式抽象
举比例如以下:
问题点:
注:当中每一个类都仅仅包含一个方法。这些方法各自是:create、display和copy等,因此存在命令式投象坏味。这样的问题不仅会添加类的数量,还会添加开发和维护工作复杂性。并且将本应内聚的方法进行了不必要的分享。解决方式
注:依据高内聚原则。统一归集到一个Report类中。
3、不完整的抽象
抽象未支持全部互补或相关的方法时,将导致不完整的抽象,比方一个抽象的公有接口提供了用于分配资源的initalize()方法。可是却没有提供删除或者回收资源的方法dispose(),这样的情况下就属于不完整的抽象。
一些常见的互补方法对例如以下:
列一 | 列二 | 列三 | 列四 |
---|---|---|---|
min/max | open/close | create/destroy | get/set |
start/stop | print/scan | first/last | begin/end |
source/target | lock/unlock | show/hide | up/down |
enable/disable | acquire/release | left/right | on/off |
供大家參考。
4、多方面的抽象
对象被赋予不止一项职责时,将导致这样的问题。
举比例如以下:
* 问题点
java.util.Calendar类承担了多项职责,不仅提供了日期相关的功能,还提供了与时间有关的功能,存大多方面抽象。由于同一时候支持日期和时间的方法,Calendar类接口非常大且难为理解。在JDK7中,java.util.Calendar类包含了2825行代码,有67个方法和71个字段。
- 解决方式
对于Calendar类,一种可能的重构是,将Calendar类与时间相关的功能提取到新类Time中,并将相关方法和字段移到新提取的类中。在Java8中引入了一些支持日期和时间的新类,这些类位于java.time中。
5、不必要的抽象
举比例如以下:
* 问题点:
public interface WindowConstants {
public static final int DO_NOTHING_ON_CLOSE=0;
public static final int HIDE_ON_CLOSE=1;
}
注:这个接口是典型的常量接口javax.swing.WindowConstants,为啥用接口来存储常量。由于首先枚举是jdk1.5才引入的。其次通过接口中定义常量。可方便类通过继承而不是托付来使用它们,由于通过实现接口。类可方便的訪问接口中的常量,为什么不使用类来存储常量呢。由于接口支持多继承。
那么接口这样定义常量有哪些问题呢?
A、派生类被无关的常量影响。
B、这些常量属于实现细节。通过接口暴露它们违反封装原则。
C、接口中存储常量。改动它们会影响其它使用者。
- 解决方式
将WindowsConstants定义为枚举,直接使用。
6、反复的抽象
依据DRY原则规定:对于每一个技术点。系统中都仅仅能有一个明白的表示。
导致反复抽象的原因有:
A、复制-粘贴编程手法
B、即兴维护
C、交流不畅
举例说明:
* 问题点:
java.util.Date和其派生类java.sql.Date同名,这两个类位于不同的包中,编译器不会由于它们同名而报错。但这让使用者一头雾水。这样将导致二义性。
- 解决方式
将Date名称前面加上用途限定语。比方java.sql.SQLDate更合适。
三、小结
由于内容太多,我们在第一部分仅仅介绍抽象型设计原则,接下来我将继续写模化型设计原则,封装型设计原则和层次化设计原则,与大家深入讨论从设计角度来看,什么样的代码才是真正的好代码。
由学习《软件设计重构》所想到的代码review(一)的更多相关文章
- 13 JSP、MVC开发模式、EL表达式和JSPL标签+软件设计架构---学习笔记
1.JSP (1)JSP概念:Java Server Pages 即java服务器端页面可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码用于简化书写!!! (2)原理 ...
- AOP软件设计
什么是面向方面的编程? 为什么面向方面的软件设计? 术语 关注 视口 关注点分离 人工制品 横切 方面 编织 零件 形式主义 第二节 案例研究 关注 人工制品 横切 方面 AspectJ 加入点 切入 ...
- 我的敏捷、需求分析、UML、软件设计电子书 - 下载(持续更新中)
我将所有我的电子书汇总在一起,方便大家下载!(持续更新) 文档保存在我的网站——软件知识原创基地上(www.umlonline.org),请放心下载. 1)软件设计是怎样炼成的?(2014-4-1 发 ...
- 【转】PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数
原文地址: PHP 杂谈<重构-改善既有代码的设计>之一 重新组织你的函数 思维导图 点击下图,可以看大图. 介绍 我把我比较喜欢的和比较关注的地方写下来和大家分享.上次我写 ...
- 敏捷遇上UML-需求分析及软件设计最佳实践(郑州站 2014-6-7)
邀请函: 尊敬的阁下:我们将在郑州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实 ...
- 基于Qt的遥感图像处理软件设计总结
开发工具 VS2008+Qt4.8.0+GDAL1.9 要点 接口要独立,软件平台与算法模块独立,平台中各接口设计灵活,修改时容易. 设计软件时一步步来,每个功能逐一实现,某个功能当比较独立时可以 ...
- 零基础入门学习UI设计指南
第一步:认识设计启蒙必备知识 学习一项技能,尤其是已经有一定沉淀并在各行各业有广泛应用的技能,就一定要对它先有充分的认知.在开始正式学习前,你需要花足够的经历去了解和查阅它的起源.发展.应用.未来. ...
- 《重构--改善既有代码的设计》总结or读后感:重构是程序员的本能
此文写得有点晚,记得去年7月读完的这本书,只是那时没有写文章的意识,也无所谓总结了,现在稍微聊一下吧. 想起写这篇感想,还是前几天看了这么一篇文章 研究发现重构软件并不会改善代码质量 先从一个大家都有 ...
- 《重构——改善既有代码的设计》【PDF】下载
<重构--改善既有代码的设计>[PDF]下载链接: https://u253469.ctfile.com/fs/253469-231196358 编辑推荐 重构,一言以蔽之,就是在不改变外 ...
随机推荐
- TPC-H数据导入MySQL教程
0. TPC-H是啥 TPC-H是TPC提供的一个benchmark,用来模拟一个现实中的商业应用,可以生成一堆虚构的数据,且自带一些查询,可以导入到各种数据库中来模拟现实需求,检查性能. 具体是怎样 ...
- lr场景运行报错的解决方法
- C++后台研发面试总结
前言: 从中秋到国庆这几天面试了几家公司,有大公司也有小公司,连续几天面试没有系统的整理整理,正好有时间系统的整理一下,好多考点牛客的大佬们都分享过了,虽然每个人的方向不相同,不过多看一些总能找到一些 ...
- jquery 选中 未选的几种方法
---恢复内容开始--- jquery判断checked的三种方法:.attr('checked): //看版本1.6+返回:”checked”或”undefined” ;1.5-返回:true或 ...
- BZOJ1102 [POI2007]GRZ山峰和山谷 [BFS]
题目传送门 GRZ山峰和山谷 Description FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷.为了能够让他对他的旅程有一个安排,他想知道山峰和山谷的数量.给定一个地图,为FGD想要 ...
- Mybatis源码分析之参数处理
Mybatis对参数的处理是值得推敲的,不然在使用的过程中对发生的一系列错误直接懵逼了. 以前遇到参数绑定相关的错误我就是直接给加@param注解,也稀里糊涂地解决了,但是后来遇到了一些问题推翻了我的 ...
- http请求,HttpClient,调用短信接口
项目中安全设置找回密码的功能,需要通过发送短信验证绑定手机,通过绑定的手机号验证并重新设置密码. 因为项目是通过maven管理的,所以需要在pom.xml文件中引入jar包, maven引入的jar包 ...
- 批量 修改 android eclipse 项目名
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 最外层的 文件夹名字.
- 【Kruskal+贪心思想】BZOJ3624-[Apio2008]免费道路
国庆万岁!!!!! [题目大意] 给定一张无向图,有两种边的类型为0和1.求一个最小生成树使得边0有k条. [思路] 跑两次Kruskal. 第一次的时候优先选择边1,然后判断有哪些边0还不能连通,那 ...
- Mac 下解压NDK .bin文件
Mac Android Studio 开发NDK,首先下载NDK文件----->android-ndk-r10d-darwin-x86_64.bin 1.打开终端获取文件权限 chmod a+x ...