今天,Venkat Subramaniam 就关于清除代码异味的话题给我们做了一个非常有趣的演讲。下面就是我记录的一些他的话。
为什么我们需要有质量的代码?
- 敏捷开发方法是用来应付那些要求代码做大量改动的反馈信息的方法。
- 如果程序没有用一种好的表达方式来表现,那程序会很难读,难维护,难修改。
什么是代码异味?
- 代码异味是一种由写的很差的代码引起的一种有臭味的感觉,一种程序什么地方会有问题的感觉
- 异味更多的是来自一种直觉,而不是一种有据可查的标准,当你看到有味的代码时你就“感觉”到了
- 如果你不把异味清除,不久之后你就会习惯这种气味,不再对它有察觉
- 用任何语言都能写出有异味的代码:即使最简单安全的语言,你也能做出天才才能想出的蠢事:)
-
我们经常会意识不到自己在写很臭的代码,经常需要外人为我们指出这点
- 边注:如果你不想刻意去批评某人的程序,不要说“太愚蠢了”,要说“哦,这很有意思…。可有一种更好的方法你知道吗”
重复的代码
- 会引起程序里面多个地方相同的错误
- 印度小伙:每两个月我们都会把这相同的错误修改一次
- Venkat:你们去掉了重复的代码了吗?
- 印度小伙:你说的这个方法不错!
不必要的复杂
- 程序员本质上讲高兴去处理复杂的问题
- 复杂最恐怖
异常处理
-
问:有什么比一个空的异常捕捉代码更糟糕的?
-
try{... } catch (Exception e){}
-
-
答:一个带有注释的空异常捕捉代码!
-
try{... } catch (Exception e){// is this required? }
-
- Java的异常检查:好还是不好?
- 如果你不想处理一个异常,就把它传递下去
- 如果你想捕捉两个异常,使用两个catch代码,不要只写一个而用If条件处理
Switch语句& 按类型的条件判断
- Switch语句和按类型的条件判断通常可以用多形性来代替
长方法
- 你不能在一屏上看到整个方法
- 这通常意味着一个方法承担这多重任务
- 难于调试
- 不可测试
- 难于重用-> 导致程序员从方法的其它地方拷贝粘贴出重复的代码
- 复杂的条件语句-> 挑战大脑的逻辑分析能力
- 方法长度:组织归纳水平比控制代码行数更重要
方法组成模式
- 方法里的所有语句都必须处在同一个归纳层次上
无用的注释
- 让代码自我表白
- 标注为什么这样,而不是如何这样
- 对方法表现进行描述等于重复表现
-
这样的注释等于重复写一遍代码
-
i += 1 //递增
-
-
长方法里用来描述这个方法有不同的功用的注释
- 把里面的功能片段提取成小方法& 删除注释
- IDE排泄物:IDE自动产生的注释空白占位符
-
糟糕的注释通常产生于TDD*
- *(TDD:Threat driven development,恐吓驱动开发)——你应该为方法的表象写注释,你应该为长方法写注释,等
-
产品里的注释:
-
//上帝保佑,我实在不知道这是什么意思
-
变量名称
- 使用能表意的名称
- 不要用单个字母做名称
- 也不要使用太长的名称
继承
- 继承更多的是被滥用了
- 组合通常优于继承
- 在一对一关系中使用继承,满足Liskov替换原则
- 不要用继承来实现方法重用
- 重用方法时,委托是个更好的选择
粘手的语言
- 这种语言更容易导致犯错误
最臭的代码
- 冗长的类
- 重复的代码
- 淘汰的方法
- 不必要的塑型(cast)
- 过度使用设计模式
代码除味
-
代码复查!
- 写出之后尽快进行
- 要增量进行
- 要复查测试用例
-
可使用结对编程
- 但要保持结对伙伴的经常变动,否则你会习惯你的气味,不再会有察觉
- 结对伙伴一、两天调换一次
一些设计原则
一些参考书籍
- 代码整洁之道(Clean Code)
- 代码大全(Code Complete) 2
- 程序员修炼之道(The Pragmatic Programmer)
- 敏捷开发修炼之道(Practices of an Agile Developer)
- Smalltalk Best Practice Patterns
- 实现模式(Implementation Patterns) (from @protoiyer)
问和答
- 关于使用代码检测工具,例如PMD:这样的工具非常的有用,它能让你捕捉到很直接的问题,使你的代码复查工作专注于高层面的设计原则问题
- 关于IDE上附加的工具:不要自己去运行它们。让这些工具在后台自动的运行(或智能化)
- 动态语言里需要重构吗:动态语言里没有太多的自动重构工具,但程序员仍然应该手动的重构
- 关于动态语言的设计模式:每种语言都有自己的模式和特色。例如:smalltalk的execute around method模式
-
关于掌握多种语言
- 你应该知道处理一个问题的多种范式,多种风格和多种方式
- 一种语言中学到的特色方法应用到其它语言里
- 知道各种不同方式的各自风险
- 关于编程语言趋势:对函数性编程,移动设备编程兴趣浓厚
- 关于著书:长时间的思考书中的各项主题,多做这方面话题的讨论,吸取精华。当开始动手去写时,已经胸有成竹,2周内把书写成
- 关于思考文献:思考文献很有用,但你也要多看看批评性的思考性文章,它们是关于你如何去思考的(double loop learning?)
- 关于学习:在用户组里跟其它人合作,交流,讨论。你并不能学到所有的东西,但要努力缩小自己的“你不知道你不知道的东西”,让它成为“你知道你不知道的”
我要评论
本文来自:
ITeye博客频道-清除代码异味
相关推荐
在这种情况下,最好保持特定大小的内部坐标区,即使周围文本溢出了图窗也应如此。您可以控制 x 轴、y 轴和 z 轴的相对长度(图框纵横比),也可以控制一个数据单位沿每个轴的相对长度(数据纵横比)。注意,在上坐标区中,内部区域会缩小以适应文本,但文本不会溢出图窗。在下坐标区中,会保留内部区域的大小,但部分文本被截断。将数据纵横比设置为一个由正值组成的三元素向量,这些正值表示沿每个轴的数据单位的相对长度。例如,创建一个带有两个坐标区的图窗,并为每个坐标区位置指定相同的宽度和高度。例如,绘制一个拉长的圆的图。
一、功能 设置坐标轴范围和纵横比 二、语法 1.axis(limits) 指定当前坐标区的范围。以包含 4 个、6 个或 8 个元素的向量形式指定范围。 2.axisstyle 使用预定义样式设置轴范围和尺度。 例如,将样式指定为equal以便沿着每个坐标轴使用相等的数据单位长度。 3.axismode 设置 MATLAB®是否自动选择范围。将模式指定为manual、auto或半自动选项之一,例如'auto x'。 4.axisydirection 其中ydi...
2、技术创新带来的效率革命:随着Java技术的不断成熟与创新,新的开发工具、框架和平台不断涌现,极大地提高了开发效率和项目质量。如何缩小这一差距,甚至在某些领域实现超越,不仅是技术层面的挑战,更是对整个行业生态的深刻反思。1、持续热门的市场地位:Java作为编程语言领域的常青树,其强大的生态系统、广泛的应用场景以及稳定的性能表现,确保了其在市场上的持续火热。6、工作性质的变化:随着自动化工具与框架的普及,Java开发中的CURD工作比重增加,使得部分开发者感到工作缺乏挑战性和成就感,技术乐趣逐渐褪色。
Collection: 可以存储不同类型的对象,而且随着存储对象的的增加容量自动增加。 添加的都是对象,不能是基本类型。 每种集合存储数据的方式是不同的,也就是使用的数据结构是不同的。 Collection中重要的接口为:List,Set。 List: 存储的对象是有序的,可以重复的。(有序是指集合中对象的顺序和添加对象的顺序是一致的。) List: ArrayList
总结 一:开发java程序的工具: ①记事本 ②Eclipse 二:Java 程序的控制台: ① Scanner从控制台输入信息,从*(包括所有的库,scanner也包括在内),scanner库里面寻找。 ② 输出语句用System.out.print(print后面加上ln代表换行。 三:程序的注释 : ① 单行注释(用//) ②
如果你做过很多java程序,你可能对java集合类很熟悉,例如Vector和ArrayList。你可以创建一个集合并向其中增加元素: List lst = new ArrayList(); lst.add(new Integer(37));在这个特殊的范例中,一个整型值37用于构造一个Integer封装类对象,然后那个对象被加入到列表。这个简单的范例展示集合的一个基础-他们用于操纵一列
反射: 反射就读取class文件,获取该文件中的属性、方法等, 作用:用来获取指定路径下的class文件中所具备的的所有属性和方法。 //返回Class对象的方式之一:getClass(); //每一个引用数据类型都有一个getClass的方法,返回的是该类的Class对象 public static void reflex() { User user = new User(); Class cls = user.getClass(); Class cls2 = user.getClass()
JAV中类、实例与Class对象 类 类是面向对象编程语言的一个重要概念,它是对一项事物的抽象概括,可以包含该事物的一些属性定义,以及操作属性的方法。面向对象编程中,我们都是以类来编码。 实例 简单理解,就是new,就是对类的实例化,创建这个类对应的实际对象,类只是对事物的描述,而实例化就相当于为这个描述新开辟了一块内存,可以改变这块区域里的各种属性(成员变量),当然...
Java 阻塞队列 ArrayBlockingQueue LinkedBlockingQueue SynchronousQueue 用put() 和 take() 是阻塞 不要用poll()和offer() ,要用也要用带时间参数的 锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得...
return格式 修饰符 返回值类型 方法名(参数列表){ //代码省略… return 结果; } 修饰符: public static 固定写法 返回值类型: 表示方法运行的结果的数据类型,方法执行后将结果返回到调用者 参数列表:方法在运算过程中的未知数据,调用者调用方法时传递 return:将方法执行后的结果带给调用者,方法执行到 return ,整体方法运行结束 小贴士:return 结果; 这里的"结果"在开发中,我们正确的叫法成为方法的返回值 例 刚刚写的热乎的 这是1到10的总和 publi
天轰川(田洪川) 一个中国人 一个四川人 一个剃了眉毛将 .NET 拉下神坛的人 一堆视频 的影响力 超过微软过亿的推广方案 他用执着诠释着人性化科技的含义 功勋着著 不过一个行业的顶级人才竟然经常为了生活而担忧 很真实 因为这两篇太安逸了,东西很多,很实用,所以转到我格子里!总的来说,如果你要找js 的东西,而不看这两篇的话,肯定要多花好多时间!!哈哈!!如果你
一、方法引用 1.1 概述 Lambda表达式中,要重写的方法可以用另一个简单的方法所代替,即返回值和所需参数一致,就可以使用方法引用的来进一步简化Lambda表达式。 1.2 对象::实例方法 Consumer<String> cus = (x)-> System.out.println(x); Consumer<String> cus1 = System.out ...
matlab
matlab plot是正方形的 怎么变成长方形 应该是画完之后,x,y坐标轴的比例不一致导致的变形 在画图之后加一句 axis equal 让x,y轴的比例一致就可以了
<br />a=linspace(1,2,10)<br />plot(a,'--pr','linewidth',1.5,'MarkerEdgeColor','r','MarkerFaceColor','m','MarkerSize',10)<br />legend('a','Location','best')<br />title('a','FontName','Times New Roman','FontWeight','Bold','FontSize',16)<br />xlabel('T','Font
.坐标轴设置一、范围设置:1. axis([xmin xmax ymin ymax])设置坐标轴在指定的区间2. axis auto 将当前绘图区的坐标轴范围设置为MATLAB自动调整的区间3. axis manual 冻结当前坐标轴范围,以后叠加绘图都在当前坐标轴范围内显示4. axis tight 采用紧密模式设置当前坐标轴范围,即以用户数据范围为坐标轴范围比例:5. axis equal 等...
以x轴为例, 限制x轴的范围: xlim([0,100]) 命名x轴刻度 xticklabels({'a','b','c'}); 自定义x轴刻度间隔 xticks(0:10:100); %这样x轴会每隔10显示一个刻度 如果需要另外定义这些刻度的名字,可以搭配xticklabels xticklabels({'a0','b10',c'30',...});%为说明效果,省略了部分内容,写代码时...
daspect([1 1 1]) 是设置坐标轴的长宽高之比等于1 axis equal是将坐标轴的长度单位设成相等,理解下,还是有所区别的,出现的是默认值,是不一样的,这两个函数也是为了更好地方便用户,
Mathworks Matlab是一款非常专业的数学计算软件,该软件提供了多个领域的分析方案,有用语言基础、数学、图形、数据导入和分析、编程脚本和函数、高级软件开发、桌面环境编程等多种数据计算,提供不同行业的函数计算公式以及函数的代码计算,不过很多用户在使用Mathworks Matlab制图后,可能某些坐标轴的位置不是我们想要的,这时我们即可通过命令进行修改,下面看详细的修改方法吧!大小:75....