1、重复代码
解决方案:
2、函数过长和参数列过长
修改点:
解决方案:
3、过大的类
解决方案:提炼新的独立类或者子类
4、参数列过长
解决方案:
5、发散式变化(一个类受多种变化影响,貌似就是单一职责原则)目标:外界变化和需要修改的类一一对应
修改点:软件一旦发生多种变化,但是都修改同一个类,说明此类职责重复
解决方案:找出某种特殊原因造成的所有变化,然后将它们提取到另一个类里面
6、霰弹式修改(一个变化修改多个类)目标:外界变化和需要修改的类一一对应
修改点:软件一旦发生变化,造成要修改很多类
解决方案:找出某种变化引起的不同类中的众多修改点,将各个类中修改点放到一个类中
7、依恋情节
修改点:
当一个类的函数为了计算经常调用另一个类的一大堆的函数时就表示出现了依恋情节。
1和0的世界里面出现了如此具有文艺气质的词,那么我们就用文艺的手法去理解:你们家的女朋友经常去找别人家的汉子时,你多多少少需要知道坏了。
解决方案:
如果这段代码完全依恋另一个类,那么将此部分出现依恋情节的代码提炼成函数放到另一个类里面(这告诉我们当一个女人完全不爱你的时候要学会放手?)
然而很多时候并非这么简单,它两个类都有依恋呢?(然而很多时候并非这么简单,她两个都爱呢?)
那就判断哪个类拥有最多被此函数使用的数据,然后就把此函数和那些数据摆在一起。(判断她爱哪个的优点多一点,就让她去找谁吧?)
难怪大家都说程序员都是好男人@_@
然而Martin大神多说了一句:
如果先提取方法将这段代码分割成不同的数个较小的独立函数上述步骤会简单很多。(请恕我直言,左腿和左手我要了,刀交给你了,你随意?)
8、数据泥团
修改点:
所谓数据泥团就是指那些经常一起出现的数据,比如一些经常一起出现的参数,举个例子:分页参数
解决方案:
数据泥团应该拥有他们自己的类,就像几个好基友需要让他们住在一起
9、基本类型偏执
解决方案:
使用一些小对象比如邮编类,电话号码类将此类数据应用起来
使用枚举类型将或者小对象去替代那些类型码
10、少用Switch
解决方案:
11、平行继承体系
修改点:每当你为某个类增加一个子类时,必须为另外一个类增加子类,那么就有问题
解决方案:让一个继承体系的实例去引用另一个继承体系
12、冗赘类
解决方案:如果某个类失去了价值,应该将其去掉,比如父子类之间区别不大,那么可以合并,或者将其搬移到另一个类里
13、夸夸其谈未来性
不要去考虑未来性,如果用不到就不值得,未来的事情就交给未来,做好现在的事情即可
14、令人迷惑的暂时字段
修改点:某个实例变量仅为某种特定情况而设,这样的代码就会不易理解,因为你会认为所有时候都会需要它的所有变量。
解决方案:
15、过度耦合的消息链
修改点:一个对象请求另一个对象,然后后者再请求一个变量,然后后者再请求一个变量这就是消息链
解决方案:
隐藏委托,在前一个类中写一个函数直接调用第三个类的函数,即尝试把函数链写在第一个类的一个新函数中
16、中间人
修改点:
过度运用委托关系
解决方案:
17、狎昵关系
当看到这两个字的时候我查了一下字典,狎妓的狎(xia),一个比较猥琐的字眼,当然你不介意的话也可以称为搞基关系.
修改点:
搞基关系的意思是,两个类之间花太多时间探究彼此的PRivate部分,就像两个男人喜欢探究对方的私处一样。
解决方案:
18、异曲同工的类
解决方案:
其实差不多就是重复代码的问题,就是两个做相同事情的函数或者类,唯一的区别在于,当这两个类差不多的情况下可以提取一个父类
来解决问题
19、不完美的库类
修改点:
简而言之就是别人写的类不好用时,就比如一个引用的动态链接库,你又改不了这个东西时
解决方案:
以下并不是重构作者的解决方案:
因为这本书真的是太老了
对于应用.net的我们可以考虑用一下partial类或者扩展函数
partial类示例:
namespace 重构测试程序{ class Program { static void Main(string[] args) { var test = new Encoding(); Console.WriteLine(test.我就是个中文函数你拿我怎样吧()); Console.ReadKey(); } }}namespace System.Text { public partial class Encoding { public string 我就是个中文函数你拿我怎样吧() { return "有种你打我啊"; } }}
扩展函数示例(老实说我在实际项目中没用过这玩意,这玩意虽好,但是吃螃蟹的恐惧让我并不敢用):
namespace 重构测试程序{ class Program { static void Main(string[] args) { var test = new StringBuilder(); Console.WriteLine(test.我叫扩展函数("Troy123")); Console.ReadKey(); } } public static class 中文编码类 { public static string 我叫扩展函数(this object obj, string name)//扩展函数 { return name + "最喜欢写测试代码的时候用中文了"; } }}
20、纯稚的数据类
修改点:
就是说这个类拥有一些字段,并且有一些读写这个字段的函数
更简单的说就是不用公共字段,不要把需要隐藏的东西暴露出来(不要把你的私处暴露出来(#‵′)凸)
解决方案:
字段封装成方法来调用(.NET的我们用属性就好了)
特别是对于容器类的字段要控制好它的封装,
21、被拒绝的遗赠
修改点:
当子类不需要继承父类多余的属性和方法时
这个修改点在Martin看来一般并不是很严重,很多时候可以不去理睬,这个视具体情况而定
我的理解是,如果子类继承多余的东西并没有引起误解和较差的可读性,那么其实可以不理睬
解决方案:
22、过多的注释
修改点:
这里并不是说注释不重要,而是说你这段过多的注释可能是因为你有一段超烂的代码而导致你不得不写这么多注释
注释除了用于标注将来之外,更应该用在你那些并无把握的地方,而不是为了一段超烂的但是你理解了的代码写一段超长的注释。
解决方案:
新闻热点
疑难解答