`
phpxer
  • 浏览: 71714 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

【转】Bad Smell重构和设计的标准

阅读更多
原文网址:http://blog.csdn.net/shendl/archive/2005/10/19/509556.aspx


-------“与其无尽的等待完美的设计,不如立刻着手实现可行的设计,然后再在设计出现臭味的时候重构实现!”



引言


今天,一位初学编程的朋友对我说,他写的类要么是数据类,要么是操作类。似乎写得不太好。于是,我看了他写的代码。他的类虽然编得不怎么样,但是放在他的小项目中,并没有发出多浓的bad smell。所以,我告诉他,他的类写得不错,并无不妥。

在回家的路上,我回想起这个他的这个问题,觉得有必要好好探讨一番,遂作此文。



正文



以前有一位朋友,让我给他的代码排错,我打开他发过来的代码,一股浓烈的臭味扑面而来----他居然使用中文作为变量和方法、类的名字!

我差点被这个臭味熏死!我问他,怎么可以使用中文作为变量名。他说,java用中文作变量名没问题的,是他的老师告诉他们这样子做的。

天呢!看来又是一个拿到毕业证书又立刻回到课堂教书的家伙!真是误人子弟呀!



Kent beck用bad smell来表示重构的适当时机,真是一语道破真谛!

Bad smell是代码好与不好的最天然的分界线!

一、        bad smell与代码的优劣

食品有做得好不好之分。其中一个重要的指标就是保质期。好的食品,保质期就长,坏的食品保质期就短。

对于代码来说也一样。也有一个保质能力的问题。好的代码,入口芬芳。坏的代码早早就变质了,而且随着时间的推移越来越臭,直到最后,我们只好把它扔掉----虽然它也曾经是我们花钱买来的。

对于食品来说,当然是保质期越久的食品越好。而对于代码也一样,我们都希望自己的代码持久芬芳。但是,保质期久的食品,制造成本自然会增加,而也许我们只需要这袋食品保质7天就成了,而保质1年对于生产来说实在是太大的浪费。同样,如果我们的代码只要保质3个月就可以了,我们如果执着的提高质量,让它可以保质3年,也是浪费了Money。

二、

这个世界上又终极完美的东西吗?没有,绝对没有!

以前,我们的数学、物理,还有哲学,逻辑学等等,总是追求完美的公式演绎,精确的度量,“最科学的…人类社会的最高阶段…”,最佳决策等等。

但是,追求完美的结果却总是惨痛的失败!、

“上帝不会让人类看穿整个世界”!

今天,已经有很多学者明白了这个道理。

“与其无尽的等待完美的设计,不如立刻着手实现可行的设计,然后再在设计出现臭味的时候重构实现!”

数学中出现了模糊数学。虽然我们无法精确的知道到底是多少,但是我们知道它会在什么之间。也就是说,我们知道“香well-smell和臭bad-smell”之间的分界。这就足够了!

物理学家们也明白了粒子测不准原理。这个世界上有很多东西是绝对随机的。也明白了夸克的内部我们永远无法认识。因为打碎夸克所需的力量大于整个宇宙的能量之和。“君子有所为,有所不为”!不要去做得不偿失的事情!“追求完美”就像是夸父追日,愚不可及!

“少谈点主义,多干点实事”胡适语。哲学家们业务实起来了。邓公的“实事求是”把中国人从哲学的虚妄追求(实际是空想)中解脱了出来。20多年里,抛弃理想(实际是空想)的中国人富了起来!中国人上天了!

逻辑学以前研究最佳决策。此外,管理学,军事指挥学等等的教授们也钻研与此。但是,今天,这些社会科学家们也明白了“完美是虚妄的”这个道理。现在MBA,工程硕士,工程博士,案例教学这些实际的东西大行其道。逻辑学现在也转而研究“较优决策”。



好了,说了这么多,似乎有些跑题了。以上这些其它专业的科学的发展经历,都无一例外的证明了“完美的虚妄”。我们做任何事情,都要有“先干起来再说的精神”。“瞻前顾后”“唯唯诺诺”者必将一事无成。

“与其无尽的等待完美的设计,不如立刻着手实现可行的设计,然后再在设计出现臭味的时候重构实现!”

比如说,我们接到一个项目,我们经过思考,获得了一个可行的设计方案,然后着手实现。此时,可能有一个小功能。我们是使用GOF23个设计模式,用n个类实现呢,还是立刻用10来行代码解决呢?我们应该选择“可到达目标的简单方案”。这是XP方法的一大原则。现在,这一段代码散发着well-smell。

过了几天,我们又增加几项功能。再看到这段代码时,它已经散发出bad smell了。

也许是因为,我们的代码大大增加了,一段语意含混不清的代码,让阅读者头晕。也许是因为,出现了大量代码的重复,或者是我们这一段不太“香”的代码被很多代码所调用。



为什么同一段代码,一会儿挺香的,不需要改进;一会儿又很臭,急需重构呢?答案是Context上下文,或者说是“环境”。



还记得以前学习语文和英语的时候,最强调的就是“语境”了。同样一句话,放在名著里,就是经典,放在我们的作文里就是败笔。

其实,代码的好坏,和语文的语言的好坏是最最类似的。一个软件就和一篇文章一样。

1,            软件的语言,用的是编程语言,有着特殊的语法;

而一般的文章,用的是汉语、英语、法语等等。

2,            软件的读者是程序员,他们学会了编程语言,如java;

文章的读者也一样是人,他们会文章的语言,如中文。

当然,也有不同。软件除了人可以看之外,还可以被编译器执行;

而我们一般的文章就不行了。

但是,软件实现的好坏,bad smell,well smell的判断者是人,而不是编译器。Well smell的代码常常比bad smell的代码更加低效。

因为,在软件的两个读者中,程序员是远远比编译器重要的读者。因为程序员的小时薪可是比电脑每小时运行的费用贵多了!

如果,建筑图纸是清晰的,那么工程师们建造房子,修改房子就容易多了。如果建筑图纸杂乱无章,那么新来的工程师要开展工作就需要更多时间的学习。对于通常是很复杂的软件来说,也许理解代码的工作量会大的不如重新编写代码!

软件代码,就如一篇说明文。

如果这篇说明文简单易懂,那么这篇文章就是散发着“诱人芬芳”的文章。

如果这篇说明文晦涩难懂,那么这篇文章就是散发着“恶臭”的文章。



同样的代码放在这篇软件里,它散发着“诱人芬芳”;放在另一篇软件里,它散发着“恶臭”。

因为,对于不同规模的软件,对于不同复杂度的软件,“简单易懂”是一个不同等级的要求。

对于大规模,高复杂度的软件。“简单易懂”意味着精巧的设计和实现。

而对于简单的软件,“简单易懂”意味着直白的,教科书式的实现即可。

当我们的软件逐渐向大规模,高复杂度进化的时候,我们的代码段也需要进化。进化成精巧的设计----面向接口编程,OOP的高级原则,设计模式,面向方面等都可能会用上。



所以,对于一个有经验的程序员来说,我们尽管率性而为,设计和实现软件。我们的决定往往是比较正确的。当我们看不顺眼某一段代码的时候,闻到令我很不爽的Bad Smell的时候,那么,我就会操起刀,给它们开一刀,令它们重新“简单易懂”。

Bad Smell,看不惯,看不懂,不清楚,不简洁,总之,不管怎么说,就是令我很不爽的时候,我就要重构它,或者重新设计它。

那么,我们重构的目标在哪里呢?OOP的一些高级原则怎么样?面向接口编程怎么样?GOF的23个设计模式用用的话会不会好一些呢?面向方面编程AOP,分离横切关注点怎么样?等等这些好的原理、技术都可能是我们重构的方向。或者,仅仅是Martin Fowler的那些个“重构手法”就管用了!





n        结语



“我不是什么伟大的程序员,我只是一个有着很多好习惯的程序员”Kent Beck语。这句话至今记忆犹新!这个世界上有很多伟大的程序员,但我只佩服那些“有着很多好习惯的程序员”!因为,我是一个只崇拜技术的程序员。我只崇拜那些编程高手,而所谓的编程高手就是那些“有着很多好习惯的程序员”。



我也明白高手之道,但我却一直没有养成高手的习惯。所以至今还是一个平凡的程序员,伟大的理想迟迟不能实施。当我闻到浓烈的“bad smell”的时候,我常常未能像Martin Fowle那样去重构,因为节点就在眼前!


希望这篇文章能够让你明白我们应该怎样编写程序,何时重构,何时重新设计。希望你也能养成kent beck那样的好习惯。

曾经,我也追逐完美,渴望卓越,渴望一步登天,一举成为顶尖高手。但这一切都是空想,都是“水中望月”。就算强悍如Rod Johnson,Kent beck等人,也仍在学习,仍在重构自己的代码,写出的代码,编出的软件也仍在被人批评!

“千里之行,始于足下”,让我们这些菜鸟开始编程吧!当我们闻到bad smell的时候再重构吧!我们将改变这个世界,也许有一天我也会成为人人景仰的英雄,大师。成为万千程序员的偶像!

“与其无尽的等待完美的设计,不如立刻着手实现可行的设计,然后再在设计出现臭味的时候重构实现!”

-----------------------------------
很值得思考的一篇文章,开发中我总是去想更好的结构和设计,因此浪费了时间和精力。
为什么不等代码的臭味来了再重构呢?
-----------------------------
分享到:
评论
29 楼 wolfigo 2006-10-31  
robbin 写道
wolfigo 写道
庄表伟 写道
我决定了,投一个新手贴。

理由是:写这篇文章的朋友,有感想而无结论,
明显是刚看了不少书,但是还不知道怎么应用于工作实践时发出的议论。


一个帖子的命运就这么决定了。。。。。可论坛的宗旨是什么???投票决定帖子命运?

写这篇文章的朋友,有感想而无结论 结论??要是这样的话,很多帖子都可以被评为新手帖。


论坛的宗旨是“打造精品技术社区”

投票是为了请大家一起帮助维护社区的高品质

如果你觉得很多帖子可以被评为新手贴,请帮我挑选出来,以便于我来维护论坛,谢谢。
请看上下文,不要误解我的意思,呵呵。
来这个论坛也有一年多了,觉得这里的帖子注重内涵,也就是说出来的话是那么回事,有水准,自己学了不少东西。
可现在这样的感觉越来越远了。。。。。。
对投票制度持保留意见。
28 楼 robbin 2006-10-31  
wolfigo 写道
庄表伟 写道
我决定了,投一个新手贴。

理由是:写这篇文章的朋友,有感想而无结论,
明显是刚看了不少书,但是还不知道怎么应用于工作实践时发出的议论。


一个帖子的命运就这么决定了。。。。。可论坛的宗旨是什么???投票决定帖子命运?

写这篇文章的朋友,有感想而无结论 结论??要是这样的话,很多帖子都可以被评为新手帖。


论坛的宗旨是“打造精品技术社区”

投票是为了请大家一起帮助维护社区的高品质

如果你觉得很多帖子可以被评为新手贴,请帮我挑选出来,以便于我来维护论坛,谢谢。
27 楼 抛出异常的爱 2006-10-31  
写下读后感或对此事的态度
那么回帖的人就是针对你的思想
而不是针对当初写帖子作者的....
当然转贴之后
作者是不会跳出来
为自己思想作进一步解释...
只能由回贴的人去猜测
误会就此产生了
26 楼 phpxer 2006-10-31  
引用

认为如果对转贴没有一点自己的观点的
还是隐了好(就好象在挑事之后坐山观虎斗)
考贝机械人不是什么好现象...


通常如果不是赞同作者的观点,或者作者的观点引起共鸣,不太可能进行转贴。如果认为没有讨论的必要,也不需要转贴。
我之所以转贴,只是觉得这个帖子值得思考。并没有打算做个拷贝机械人。


根据上面诸多回帖的意思,JavaEye的目标就在于原创/高手探讨吗?打造中国最好的软件社区并不能只限于此吧?

当然,任何一个论坛都不能 转贴 泛滥,任意的转贴,无目的性的是不应该的,而且会给论坛带来负面影响。
25 楼 抛出异常的爱 2006-10-31  
phpxer 写道
引用
一个人月大约是两千行吧.....
巨寒这种一个类里有上百行代码的东东....
一般两百行以上就看看能否重构了...


9000行代码是前前后后写了三个多月吧,并不是一个类。而是12个包,101个类。

引用
我决定了,投一个新手贴。

理由是:写这篇文章的朋友,有感想而无结论,
明显是刚看了不少书,但是还不知道怎么应用于工作实践时发出的议论。

原作者是个在校研究生,请从文章给出的原文链接看具体情况。

我转贴的文章先是被隐藏,后来被精华,最后清除投票。大家这么多人关注JavaEye的建设,十分敬佩。本人工作不到一年,水平确实不怎么样 :)。认为可以对转贴人给低分(即使转的帖子确实很优秀,能够引起讨论,引人思考),但是不允许转贴则没有必要,任何值得肯定的文章都应该得到肯定,是吗?


认为如果对转贴没有一点自己的观点的
还是隐了好(就好象在挑事之后坐山观虎斗)
考贝机械人不是什么好现象...
24 楼 phpxer 2006-10-31  
引用
一个人月大约是两千行吧.....
巨寒这种一个类里有上百行代码的东东....
一般两百行以上就看看能否重构了...


9000行代码是前前后后写了三个多月吧,并不是一个类。而是12个包,101个类。

引用
我决定了,投一个新手贴。

理由是:写这篇文章的朋友,有感想而无结论,
明显是刚看了不少书,但是还不知道怎么应用于工作实践时发出的议论。

原作者是个在校研究生,请从文章给出的原文链接看具体情况。

我转贴的文章先是被隐藏,后来被精华,最后清除投票。大家这么多人关注JavaEye的建设,十分敬佩。本人工作不到一年,水平确实不怎么样 :)。认为可以对转贴人给低分(即使转的帖子确实很优秀,能够引起讨论,引人思考),但是不允许转贴则没有必要,任何值得肯定的文章都应该得到肯定,是吗?
23 楼 抛出异常的爱 2006-10-31  
phpxer 写道
引用
PS:你是新人所以写9000行代码的理由么?(我只限于写过5000行的sql)


我的意思是说,给她看的那个程序,9000行代码的样子,不是很大,但是被抱怨。

因为我是新人,所以按照他们的意思改。通常而言,他们可能更有经验,而且,这是尊重同事的必要。


一个人月大约是两千行吧.....
巨寒这种一个类里有上百行代码的东东....
一般两百行以上就看看能否重构了...
22 楼 庄表伟 2006-10-31  
谁说这个帖子的命运就这么决定了?
我只有19票,投了,然后说了自己的意见。

如此而已。

你回头去看看这里的帖子,哪些是精华,哪些不是精华,再来看论坛的宗旨是什么。
21 楼 wolfigo 2006-10-31  
庄表伟 写道
我决定了,投一个新手贴。

理由是:写这篇文章的朋友,有感想而无结论,
明显是刚看了不少书,但是还不知道怎么应用于工作实践时发出的议论。


一个帖子的命运就这么决定了。。。。。可论坛的宗旨是什么???投票决定帖子命运?

写这篇文章的朋友,有感想而无结论 结论??要是这样的话,很多帖子都可以被评为新手帖。
20 楼 庄表伟 2006-10-30  
我决定了,投一个新手贴。

理由是:写这篇文章的朋友,有感想而无结论,
明显是刚看了不少书,但是还不知道怎么应用于工作实践时发出的议论。
19 楼 robbin 2006-10-30  
这个帖子从哪个标准看都不能算精华,隐藏贴看起来也不像。鉴于这个帖子的争议性,我清除了对该贴的投票,大家有什么意见请重新投票。
18 楼 wolfigo 2006-10-30  
看完LZ的帖子和诸位的回复,有这样一个问题,是不是让人读不懂,或难以维护的代码就是散发bad smell的代码呢,是不是重构后的代码就便于维护,易读呢?小弟初学,请不要见笑。
17 楼 kabbesy 2006-10-30  
坐而论道不如起而行之
16 楼 bigpanda 2006-10-30  
我认为转贴不该评为精华,鼓励原创,既然要打造中国最好的技术社区,就要招请天下高手,是高手还天天转贴干什么。
15 楼 jack 2006-10-30  
nihongye 写道
re,感觉这么多人对javaeye的感情不是一般的深啊。
引用

我自己也是不大善于运用规则了,哈哈, 这个帖子我投了“精华“,现在觉得过了,最多应该投为 “良好“,
等里面的讨论很好地深入了,我投为 “精华“也可以,不知道robbin是否支持这样的功能阿。

不要这么复杂吧,有些漏网之鱼是允许的。


这种可能会出现一个规则漏洞。javaeye应该就是原创人员的集中地。转贴很难评判转贴人的技术水平。说的不好听点,转贴上20个不错的文章,有1个精华,也赚到了。这样时间久了,慢慢的就是转贴集中地了。这个是所不喜欢看到的。

14 楼 nihongye 2006-10-30  
re,感觉这么多人对javaeye的感情不是一般的深啊。
引用

我自己也是不大善于运用规则了,哈哈, 这个帖子我投了“精华“,现在觉得过了,最多应该投为 “良好“,
等里面的讨论很好地深入了,我投为 “精华“也可以,不知道robbin是否支持这样的功能阿。

不要这么复杂吧,有些漏网之鱼是允许的。
13 楼 firebody 2006-10-30  
nihongye 写道
引用
我觉得恢复之前应该说明原因或者遵循大家的意见,这个是应该的。

恢复的管理人员真是郁闷死了。

哈哈,她/他郁闷死是小事,让大家郁闷就是大事了,这对于一个口号为“打造中国最好的技术社区“的网站来说,这些事情是升级为“公事“的。 大家一起讨论,慢慢打造。
我向一个好的社区对于大家也是好事。
12 楼 nihongye 2006-10-30  
引用
我觉得恢复之前应该说明原因或者遵循大家的意见,这个是应该的。

恢复的管理人员真是郁闷死了。
11 楼 firebody 2006-10-30  
charon 写道
这个帖子的被隐藏然后又被精华,觉得会有两个效果:
1. 就帖子内容而言,一篇绝大部分在无病呻吟的重复真理的酸文,在一个技术板块被评为精华,这个舆论导向最终会使javaeye逐渐csdn化。
2. 就帖子性质而言。一篇全文转贴的文章被隐藏后旋被质疑http://www.iteye.com/topic/31101,而后又奇迹般的取消隐藏而最终成为精华。能够做的判断,要么是技术故障导致,要么是管理团队在提倡全文转贴这类做法. 但这显然是极其危险的。一方面会导致大量全文转贴现象的出现(毕竟网上真正的好文不计其数),另一方面会出现微妙的发布权问题.
hehe.拭目以待巴

我提出质疑,仅仅从我自身的观点出发,呵呵。 因为我本来希望这里面的讨论能够继续进展下去。至于是不是转贴,从我个人的观点我并不是很在意,只要里面的讨论有意义就行。

我觉得恢复之前应该说明原因或者遵循大家的意见,这个是应该的。

不过 转贴被评为 精华,这个结果确实 让论坛规则变得很微妙了。

我自己也是不大善于运用规则了,哈哈, 这个帖子我投了“精华“,现在觉得过了,最多应该投为 “良好“,
等里面的讨论很好地深入了,我投为 “精华“也可以,不知道robbin是否支持这样的功能阿。

10 楼 jack 2006-10-30  
charon 写道
这个帖子的被隐藏然后又被精华,觉得会有两个效果:
1. 就帖子内容而言,一篇绝大部分在无病呻吟的重复真理的酸文,在一个技术板块被评为精华,这个舆论导向最终会使javaeye逐渐csdn化。
2. 就帖子性质而言。一篇全文转贴的文章被隐藏后旋被质疑http://www.iteye.com/topic/31101,而后又奇迹般的取消隐藏而最终成为精华。能够做的判断,要么是技术故障导致,要么是管理团队在提倡全文转贴这类做法. 但这显然是极其危险的。一方面会导致大量全文转贴现象的出现(毕竟网上真正的好文不计其数),另一方面会出现微妙的发布权问题.
hehe.拭目以待巴


我也有同样的担心,如果转贴同样能够精华,javaeye很多设置很快就没有意义了。

相关推荐

    java重构设计.doc

    **Java重构设计** 在软件开发过程中,重构是一个至关重要的步骤,它涉及到对现有代码的改进,以提高代码...实践中,我们应该时刻关注代码的"bad smell",并采取适当的重构策略来解决这些问题,以实现更好的软件设计。

    Code Bad Smell Detector-开源

    在软件开发中,"代码坏味道"(Code Smell)是指源代码中可能存在的一些不好的编程习惯或设计模式,这些模式可能暗示着潜在的问题,虽然不影响代码的编译和运行,但可能导致可维护性、可读性和可扩展性降低。...

    java重构设计java重构设计.doc

    - **日志管理**:整理和标准化日志记录。 - **文档整理**:更新和完善文档。 - **异常处理**:正确处理和记录异常。 7. **代码的不良模式(Bad Smell)及解决策略**: - **重复代码**:提取方法。 - **过长...

    coca-master.zip

    首先,让我们深入了解一下Coca如何帮助我们识别和处理"bad smell"。Bad smell,即代码异味,是指代码中可能存在的问题或潜在的复杂性,这些可能会导致维护困难或性能下降。Coca通过分析代码结构和模式,能够检测出...

    Findbug使用指南.docx

    * 代码优化:Findbugs 可以帮助我们发现代码中的 bad smell 和潜在隐患,提高代码的质量。 * 编码实践:Findbugs 可以帮助我们养成良好的编码习惯,提高开发编码能力。 Findbugs 是一个非常有用的代码检查工具,它...

    麻省理工18年春软件构造课程阅读04“代码评审” 1

    与此同时,评审过程也是对编程原则的一个重要检验,例如,是否有代码存在"难闻的"代码(bad smell),这通常指的是那些使代码难以理解或可能引发错误的代码结构,比如冗余的代码或者复杂的逻辑判断。 在进行代码...

    林锐高质量C++编程指南

    - 设计模式:学习和应用设计模式来解决常见问题。 根据提供的部分内容,可以推测书中有以下知识点: - C++编译器和环境:如提到的WINDOWS和UNIX,表明书籍覆盖了不同操作系统下的C++编程。 - C++关键字:如提到的if...

    程序员为什么还要刷题-styleguide:我们如何编写代码

    bad counter += 1 # increments counter by one 使现有评论保持最新。 一个过时的比没有评论更糟糕。 避免写注释来解释糟糕的代码。 重构代码以使其不言自明。 避免代码横幅。 如果您需要它们,您的类可能太大了。 ...

    不良气味检测和解决时间表:节省精力的新方法

    尽管提出了关于异味检测和重构工具的建议,但是检测和解决异味仍然对软件工程师来说很耗时。 已经识别出许多难闻的气味,但是很少讨论执行检测和解决各种异味的顺序,因为软件工程师不知道如何优化顺序或确定最佳...

    InspectorGuidget:在Java代码中查找Blob侦听器的工具

    有关最新动态,请参见督导员通过在Eclipse Java编辑器中引发警告来检测GUI设计气味的工具,例如java SWING / AWT / JavaFX GUI侦听器中的Blob侦听器。 关于Blob侦听器的论文的最新版本在这里: : 如何运行...

Global site tag (gtag.js) - Google Analytics