我们虔诚追求的,乃是代码的可理解性。
 
(一)、Bad Smell
1Duplicated  Code – 重复的代码
    这是最容易看到和被理解的bad smell,如果你在一个以上的地方看到相同的代码,它一定可以改善为复用,提炼出那一段相同代码。
如果重复代码是同一个class内的二个Method,那么直接提炼出来,然后在需要处调用;
如果重复代码位于二个互为兄弟的subClasses 中,需要把重复代码提到superclass内;
如果代码间只是类似,并不完全相同,要先分割它们的相同和异处,或者用Template Method 模式;
如果几个函数以不同的算法做相同的事,就选择较清晰的一个,并统一之;
如果二个不相关的classes 内出现相同的代码,应该考虑将代码提炼到一个独立的class中,然后在另一个class中调用。等等,方法比较多。要多读源码,参考在别人的代码中,这种情况都是怎么处理的。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

2Long Method  -- 过长的方法与函数
    在我不熟悉OO的时候,总觉得程序里到处充满了delegation- 委托,就是找不到它在哪里计算,那时候总以过程式的思维来阅读,处处都是疑惑。后来慢慢就习惯了小型的函数,并且书中讲它的优点与利益 --  解释能力、共享能力、选择能力。
small method 容易理解的真正关键在于一个好名字。如果你能给method起个一目了然其作用的好名字,阅读者就可以通过名字了解其作用,一般不必去看内部怎样实现。我们应当遵循这样一个原则,每当感觉需要注释来说明一些什么的时候,就将要说明的东西写进独立函数,并以其用途(而不是实现手法)命名。
据说99%的情况下,只要用Extract Method ,找到函数适合集中在一起的地方,提炼出来形成新的Method,就可以将其改小。条件式和循环也常常是需要提炼的信号。

 

3Large Class   -- 过大的类

    如果单一class做了太多了事情,这往往是代码“重复、混乱”的信号。
    可以试着将变量提出来、抽出subclass,抽出Interface,抽出domain object,逐步地把它分解变小。

 

4Long Parameter List  -- 过长参数列

   参数太长会造成难以理解,参数太多还会带来前后不一致,不易使用,一旦你需要更多的数据,或对某一项改变,修改复杂度都会越来越高。一般情况下,这些参数都可以提为一个Object,即使它确实缺乏合事的归属对像,还可以创建一个参数对像,这样对参数的修改就化为对对像值域的修改。
   但是这里还要注意一点,如果写的方法参数过长,或可能的变化过于频繁,就需要考虑一下自己的结构设计是否合理。

 

5Divergent Change -- 发散式变化

良好的设计期待在变化发生的时候,程序更容易修改。一旦需要,只在该改的地方来改,而不是若干地方都涉及。
针对某一外界变化的所有相应修改,都只应该发生在单一class中,这个class的所有内容都应该反映外界变化。为此,我们应当找出可能发生变化之处,然后将它们提炼至另一个class中。
着重指一个class受多种变化的影响。

 

6Shotgun Surgery  -- 霰弹式修改

与“发散式变化”类似,它着重指,一个变化引发多个class相应修改。
应该把所有能预见到发生的变化放一个class.

 

7Feature Envy   -- 依恋情结

这是一种经典的bad small ,某个函数为了计算一个问题,大量引用另一个对像中的数据。函数对某个class的兴趣高过对自己所在的host class 兴趣。

 

8Data Clumps – 数据泥团

常常在很多地方看到相同的几笔数据:例如二个Classes 内的相同的值域、几个函数的相同的参数列表,这些总是在一起出现的数据,应该放在一个类里面。
可以这样来评测: 删掉这些数据中的一个,然后看其它的是否还有意义,如果其它的不再有意义,这就是个明确的信息,应该为它们单独产生一个类的。

 

9Primitive Obsession – 基本型别偏执

    我们可以试着在小任务上运用小对像,例如,结合了数值和币别的money class,含起始值和结束值的range class,将原本单独存在的数值替换为对象。
    如果你有一组总是放在一起的值域、或在参数列表中看到基本型别的数据、或发现自己正在从Array中挑选数据。这些时候,不妨考虑下用Object 代替分散的数据。

 

10Switch Statements

   从本质上来讲,switch语句的问题在于重复。一旦使用,你会发现同样的switch语句散步于不同的地点,如果要为它添加一个新的case,必须找到所有的switch语句并修改它们。这时,就要考虑用polymorphism多态。

 

11Parallel Inheritance Hierarchies – 平行继承体系

    如果你为某个class增加subclass,时,必须也为另一个class相应增加一个subclass,如果你发现某个继承体系的class名称前缀和另一个继承体系的class名称前缀完全相同。消除这种重复性的一般策略是,让一个继承体系的实体引用另一个继承体系的实体,再接着用Move fieldMove method