说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

重构:仔细查看,改进代码

HTML文档下载 WORD文档下载 PDF文档下载
重构是一门改变已经正常的工作的艺术。但是重构是需要理由的。可能是设计改进,性能问题,安全角色或者很多其他的原因。

我建议你进行一个练习:当你第二天早晨开始工作的时候,重新审视你的项目源码,尝试发现进行重构的机会。就算你的领导没有要求,仍然去做。因为在工作中,你希望有一些激动人心的时候。

重构是一门改变已经正常的工作的艺术。但是重构是需要理由的。可能是设计改进,性能问题,安全角色或者很多其他的原因。改进程序的技术缺点是要冒风险的,尽管能够使其更稳定,并且可能能够提高你自己今后的生产力。

这不是为了公司或者领导好,而是为了自己。为什么?因为问题都是逐渐累积的,到达一个程度之后,你会失去对代码的控制。你将会面对苦于交付结果的境地,最终可能毁掉你的职业生涯。

好吧,让我们从一个更加积极的角度来看这个问题。在重构过程中你会学习到很多,并且很快意识到你产出了比之前更好的代码。重构越多,你就越聪明,慢慢累积直到你达到创新的级别。但是这意味着什么,你又如何知道你达到了呢?

当你发现一个明显的机会来对你当前的工作进行改进,并且你意识到至今为止还没有别人做过这样的事情(至少你找不到)。这不容易,这不容易,但这常发生在你不断重复做一件事情,并且你能够发现你如何能够使得同样的事情做得又快又好。让我用一个真实的故事来说明。

例子是在Java中进行字符串连接:一个经典问题,曾经在过去数年困扰了大量专家,但在今天可能已经被忽略了。在JDK1.5之前,尽管可读性高而且简单,但使用“+”来进行字符串连接可能产生效率极低的代码。之后,“+”操作符被换成了StringBuffer,从而真正改进了连接。使用“+”越多,则在内存中的String和StringBuffer实例越多,为了管理所有的对象花费的时间也越多。因此,开发者们被推动使用StringBuffer而忽略“+”。看下面的例子:

String title = "Mr."; String name = "John"; String familyName = "Smith";  String message = "Dear " + title + " " +                  name + " " + familyName + ",";
开发者习惯于这样写代码,但是现在被推动这么做:

StringBuffer sb = new StringBuffer(); sb.append("Dear "); sb.append(title); sb.append(" "); sb.append(name); sb.append(" "); sb.append(familyName); sb.append(",");
你可能同意第一个例子可读性高于第二个。开发者使用“+”进行字符串连接时很自然的,所以丢弃这样的形式不合适。好消息是,编译人员做了一些事情来维护这样的习惯,确保了JDK1.5会优化连接方法。代替线程安全的StringBuffer,他们建立了一个叫做StringBuilder(非线程安全,但更快)的类,并且他们确保能够像第一个例子中那样,使用一个实例就能处理所有的连接。这是一个很重要的进步,因为他们兼顾了简洁而不单纯是技术性。第一个例子在编译时会自动转换成如下情况:

StringBuilder sb = new StringBuilder(); sb.append("Dear ").append(title).append(" ")   .append(name).append(" ").append(familyName)   .append(",");
但是,在一些复杂逻辑代码中的字符串连接还是需要使用StringBuilder,因为编译器还没有那么智能,例如:

List<Student> students = studentBean.findStudents(); String intro = "The following students were approved:\n"; String listedNames = "";String separator = "";for(Student student: students) {  if(student.approved()) {    if(!listedNames.isEmpty()) {      separator = ", ";    }    listedNames += separator + student.getName();  } }String msg = intro + listedNames;messengerBean.sendMessage(msg);
如下写法会更有效率:

List<Student> students = studentBean.findStudents();String intro = "The following students were approved:\n";StringBuilder listedNames = new StringBuilder();String separator = "";for(Student student: students) {  if(student.approved()) {    if(!listedNames.length() > 0) {      separator = ", ";    }    listedNames.append(separator)               .append(student.getName());  }} String msg = intro + listedNames.toString();messengerBean.sendMessage(msg);

呃!你注意到有什么奇怪的东西了么?可能一眼看起来不是很明显,但是看看他们是如何在定义分隔符之前检查listedNames是否为空的。String类在JDK1.6中有一个可读性很好的方法isEmpty(),但是StringBuilder仍然使用相对比较老的方式。为什么他们不将StringBuilder 和 StringBuffer改为同样的方式呢?

在核心库开发的邮件列表中讨论了这个问题,没有发现什么明显原因导致他们之前没有这么做。可能只是忘记了。要感谢大规模的重构,试图改进效率低下的字符串连接方法,才能发现这样的不一致。我相信在明年推出的Java8中会有时间修复这个问题。只要在接口CharSequence加入isEmpty()方法,这样就能使得所有实现都变得同样优雅。

这可能是一件简单的事情,但是Java是一个严格审查下的复杂的语言,所以每个细节都会带来很大的影响。所以,做一些重构,发现一些改进代码的机会,同样也能够改进你使用的编程语言。让我们一起推动Java进步吧!

英文原文:Java Code Geeks

译文来自:ImportNew
生存还是毁灭:Facebook惨败真是HTML5的错? OpenStack基金会主席:一年后成熟度超越CloudStack 在线学习新编程 技巧全攻略 “英特尔杯”HTML5程序开发邀请赛侧记 C#编译器组首席工程师Eric Lippert离职 加盟Coverity Testacular:Google开源的JavaScript测试执行过程管理工具 黑莓亚洲开发者大会报道:BB10将敲开亚洲应用市场大门 挑战Google!传Facebook与Yahoo要联手开发搜索引擎 揭秘Android 4.2 开发者的天堂与地狱 11大黄金法则:顶级移动UX设计心髓 库克时代:苹果已经不是苹果 设计师必备:极简风格的Fluid UI快速原型图工具 iPhone 5发布,后乔布斯时代苹果乏善可陈 牛人妙计:HTML5应用也能像原生一样跑得快 移动周报:OpenFeint难逃关闭命运 细数与苹果恩怨史 FlyingDaggers团队专访:不浮躁,用心做真正的原创游戏! IT巨头混战:谷歌、苹果、Facebook以及亚马逊的四国演义 乐视TV:智能电视平台——Android 开发者的新空间 TIOBE 2012年12月编程语言排行榜:Objective-C冲刺卫冕年度语言 11月份浏览器市场份额 IE10已占据0.51% 亚洲高科技公司正在分享惠普、戴尔和IBM的云“午餐” Groupon创业启示:进军海外,请三思 天才之为责任:Unity CEO谈论Unity 4.0游戏引擎 中文版Evernote百宝箱上线:开发者海外推广新渠道 360产品被爆收集用户隐私 桌面安全路在何方 销售额达一万亿元 阿里巴巴成世界最大电商 共享软件海外营销策略与实战分析(武汉站)成功落幕 你未必知道的CSS故事:揭开leading的面纱 2013年 影响Web发展的5类API 《Warcraft是怎样炼成的》:多人对战、战争迷雾以及AI HBTC精彩回顾 Hadoop专家分享大数据技术工具与最佳实践 刚才的没解决 找工作, 上海。 请帮忙啊 关于在delphi中Dll的创建和调用,象登陆界面一类,dll中有窗体,求例子。 哪家网上书店信誉高,C++ builder书质量高? 关于rs.MovePrevious 100分问题:如何在sdi的view的(0,0,NULL,20)区域固定显示一定内容 VB中使用ADO连接远程数据库时的事务处理问题 在weblogic中,这个错误是怎么回事?(在线等待) 怎么用SOCKET传送一个自定义类型的数据 szbug大哥请进来拿分 幸福女人的小小要求(zt) 各位好,请问一个问题:存储过程的作用是什么,能不能举例说明一下,看了半天书,也没能明白,多谢了! 我想用循环来实现这样的语句,怎么写呢? 请问xml元素内容部分的html代码如何处理 怎样定义rect数组? 一道考试题目:考考你们自己的C++水平。 怎样用代码遍历DBGrid中的记录?急!在线等待! 为什么mov eax, [0x400000h]和mov eax 400000h汇编结果一样? 网络报表最好的解决方法是什么 高分求购web 打印控件?还有一个远程数据库,客户端打印问题帮忙解决一下 哪位高手能给一个简单的TOOLBAR控件应用的原代码?(非常需要) 哪些有钱途?哪些有前途? 讨论:MSE(软件工程)对中国目前的开发现状真的有帮助吗?来者有分 ACCESS查询语句中的DATEPART函数为什么不能执行??? php为什么安上后不能用 在VS.Net中如何使注释生成已编译的HTML帮助文件? 我想更改Win2000的开机画面,请高手指点 ADO连接数据库时的事务处理问提 对于动态生成的控件,如何确定它的名字? vb 中使用select 的问题 想把post的变量遍历,怎样实现 小问题 关于参数 如何通过一个计算机名来查出它在局域网中的IP !!!!!~~~ 急,哪里可以下载IeWebControl? 有没有方法通过分布式连接直接从sql server写数据到oracle数据库。 郁闷问题:有谁知道Textbox在运行时如果没有任何输入,它是否空值? 如何用vb做一个启动程序(在windows启动运行) 请问,怎样将一个已分好区的电子盘格式化成ext2格式??? 请教web services问题 高分求购H261解码算法 子类中怎么用基类中的一个属性? 请问有没有JB7的中文教程,高分相求!(400分) 怎样在下拉列表框中显示数据表?具体怎么做? 请教,各位是如何实现对SQL SERVER的记录加密的? Datagrid中的HyperLinkColumn如何传递两个变量值给下一页? 高手请进:怎样将一个值传递到datagrid模板列的一个textbox中?问了好久,没有人会吗? ACCESS中的DATEPART函数为什么不能执行? 怎样在下拉列表框中显示数据表?具体怎么做? davidnim(天道酬勤) ,谢谢你了! EA 哥们们想你! 过年了你还好不? 听说你去了米国。。。。。。 刘诗诗郑元畅吴奇隆 盘点令人羡慕的荧陈乔恩杨幂蔡少芬 揭秘众女星无法直视嫁入豪门未必幸福 盘点遭遇家暴的悲惨《新笑傲江湖》完结 比较各大版本的东盘点山寨明星黎丹神似杨幂 李星版杨钰赵薇姚晨蒋勤勤 北影十大校花的幸福生一个演员毁掉一部经典范冰冰杨幂古力娜扎 盘点演配角走红的新《笑傲江湖》大结局一秒变恐怖片 东日本小姐出炉 日本环球小姐松尾幸实私2013众多日本小姐出炉 哪个日本小息影11年46岁王祖贤复出 重温没有《我们结婚了》世界篇:鬼鬼吴映洁身穿2013日本小姐出炉 25岁模特夺冠日本小姐出炉:冠军松尾幸实疑似混血儿《西游降魔篇》票房破11亿 能否超《2013日本小姐出炉 25岁模特夺冠《那年冬天风在吹》9集宋慧乔赵寅成虐陈冠希谢霆锋张国荣梅艳芳 盘点明星超2013日本小姐出炉 25岁模特夺冠2013日本小姐松尾幸实夺冠 盘点历公共场所要向公众免费“送凉”买菜时遇商户斗殴公安局长徒手夺刀大河实战账户(7月21日星期一)“我是恁哥,给你捐肾的事儿听我的”以色列轰炸加沙至少 530人死亡成都出发全场5折起,3天满千返百 九火烧云 金镶玉 不走锦官城 哪有飞来全市专项治理住宅质量你看见的舌尖,是垂涎欲滴 你未见的舌20名责任人被控制 其中10人被刑拘我是一只懒小鸟 有机可乘闯成都这1个多小时 2岁半娃娃去了哪儿?快贷 帮您快速贷款 贷款利息低至5厘名人家书,分享子女教育“参考答案”30个好项目“坐镇” 本周五连锁加盟拿出实际行动 形成工作支撑中国反对在朝鲜半岛部署末端高空区域防再坚持一天明天高温暂歇 台风“麦德姆高温红色预警信号一旦发布 户外工人停余杭两幼女被杀案告破 嫌犯臧纪超昨晨联合国安理会:追究马航MH17坠毁肇
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘