我们必须培养自己的判断力Q来军_在什么时候进行重构?
如果你在一个以上地点看到相同的E序l构Q那么将他们合而ؓ一会更好?
拥有短函数的对象会活得比较好Q比较长?
间接层所能带来的全部益处Q解释能力(可读性)Q共享能力(重用性)Q选择能力Q?Q?
现在OO 语言基本解决了函数调用所产生的开销?
?你应该更U极q去的分解函数。我们遵循这样一条原则:每当感觉需要以注释来说明点什么的时候,我们把需要说明的东西写进一个函CQƈ以其用途(而非实现手法Q命名。我们可以对一l甚至短短一行代码(拥有复杂逻辑Q难以理解)做这件事。哪怕替换后的函数调用动作比函数自nq长Q只要函数名U能够解释其用途,我们也该毫不犹U的这么做。关键不在于函数的长度,而在于“做什么”和“如何做”之间的语义距离??
“如何确定该提炼哪一D代码?一个很好的技巧是Q寻找注释。它们通常是指出“代码用途和实现手法间的语义距离”的信号。如果代码需要用注释来说明其用途,那么p考虑把这D代码提炼成独立的函敎ͼq且用注释来为此函数命名。?
复杂条g式和循环液常常是提炼的信受?
如果惛_用单一的class 做太多的事情Q其内往往会出现太多的 instance 变量?
如果class 中拥有太多的代码Q也是“代码重复、乱、死亡”的l佳滋生炏V?
q长的生导致程序难以理解?
?一个class 受多个外界变化的影响 ”,则把q多个变化封装成一个新的类。即?L一起变化的东西攑֜一??
针对外界某一变化所有相应的修改Q都应该只发生在单一的class 中,而这?class 的所有内定w应该反映该外界变化。ȝ思想是Q封装变化。这个地方和设计模式的想法是一致的?
和发散式变化不同Q每ơ遇到变化,都要在多个class 中进行小的修改以响应之。他们分散在多处Q很Ҏ出错?
q里的主要思想是集中变化?
散弹式修Ҏ的是Q?一U变化引发多个class 的修?”,发散式变化指的是?一个class 受多个外界变化的影响 ”?
q两U情况下Q通过重构Q?低쀜外界变化”和“待修改cZ呈一对一关系 的理惛_地?
某个函数对其他类的数据的兴趣Q高q对host class 的兴。即对其他的cȝ数据的依赖十分大?
数据泥团指的是Ll定在一起出现的数据?
一个好的评断方法:删除众多数据中的一Ҏ据,其他数据是否是因而失M意义Q如果他们不再有意义Q你应该Z们生一个新的对象?
形成新的对象后,可以ҎFeature Envy 一些操作移x对象中?
建立多个很小Q但是很灉|的对象?
使用面向对象~程Q要用switch ?case 语句。而是用多态来替换它?
每当你ؓ一个class 增加一?subclass 的时候,必须为另一?class 增加一?subclass 。一般这两个 class 的前~相同?
cL得多余,没有价倹{?
q个往往是过度设计的l果Q对某种变化的应对,而这U变化没有发生?
变量只在特定的情形下有效Q而ƈ不是所有的情况下有效。很多情况下Q这些值域应该不属于此class Q而应该单独的提取成新的类?
用户向一个对象烦取另一个对象,然后在向后者烦求另一个对象,然后在烦求另一个对象——客户与查找q程的航行结构紧密耦合?
对象的基本特征之一是装——对外部世界隐藏实现l节——封装往往伴随委托。委托的q度q行Q就D了Middle Man ?
两个class 之间的关p过于亲密。比如,花大量的旉探究彼此?private 成分?
cd不同Q但是功能相伹{?
基础cd无法满实际的需求?
它们拥有一些值域Q以及用于访问(dQ这些值域的函敎ͼ除此之外一无长物?
子类不像l承父类的函数和数据Q这往往是承体pȝ错误?
如果子类复用父类的行为,但又不愿支持父类的接口,q种情况下Refused Bequest 的坏味道会很强烈?
注释其实是一U香呻I更多的情况下它被用作除臭剂:即代码中出现坏味道(设计p糕的代码)Q然后用注释“除臭”。这个时候我们应该对q些坏味道的代码q行重构Q然后,你会发现注释变成了多余的?
当你感觉需要注释,请先试重构Q试着让所有的注释都变得多余——代码本w就是自注释的?
注释可以用来记述“ؓ什么做某事”、“打做某事”、“无十把握的区域”,而不必记录“怎么做”?/p>
如果你想q行重构Q首要前提就是要拥有一个可靠的试环境?
“编写优良的试E序Q可以极大的提高我的~程速度Q即使不q行重构也是如此。?
“Class 应该包含他们自己的测试代码。?
“每个Class 都有一个测试函敎ͼq用它测试自p?Class 。?
保所有的试都完全自动化Q让它们查自q试l果?
只要写好一点功能,qx加测试?
一整组Qa suite of Q测试就是一个强大的“臭虫”侦器Q能够大大羃减查䏀臭虫”所需要的旉?
“实际上Q编写测试代码的最有用时机是在开始编E之前。当你需要添加特性的时候,先写相应的测试代码。听hȝ叛道Q其实不然。填写测试代码其实就是问自己Q添加这个功能需要做什么。编写测试代码还能你把注意力集中于接口而非实现上头Q永q是件好事)。预先写好的试代码也ؓ你的工作按上一个明的l束标志Q一旦测试代码运行正常,工作可以结束了。?
构徏自我试的代码?
频繁的运行测试,每次~译h试也考虑q去Q每天至执行每个测试一ơ?
单元试和功能测?
“每当你接获臭虫提报Q请先撰写一个单元测试来揭发q只臭虫。”——如何揭发?q里需要根据报告准定位。单元测试会Ҏ有帮助吗Q?
“观察Class 该做的所有事情,然后针对M一功能的M一U可能失败的情况Q进行测试。?
“测试应该是一U风险驱动(risk driven Q行为,试的目的是希望扑և现在或未来的可能出现的错误。?
“测试的诀H是Q测试你最担心的部分。?
q点和我目前的想法不大相同。我目前的想法是Q测试要对程序做100% 的保证,所以,要测试程序可能行为的每一U情况,保证其正性。按照我的想法,值域的设|和讉K函数也是要测试的。作者的意思是Q测试代码要用最低的成本Q获取最大的收益。这一点,要我在实际的环境中进行抉择?
“编写不是十分完的试q实际运行,好过对完测试的无尽{待。”——我持怀疑态度?
q用试用例前后执行的函敎ͼtearDown ?setUp Q保证测试用例之间相互隔,而非怺影响?
做一个懒惰的E序员——?
考虑可能出错的边界条Ӟ把测试火力集中在那儿?
“测试(优先Q可以调高编E速度”,q一Ҏ要在实践中验证一下,如果真是q样Q那我就要尝试在我们部门推行q种Ҏ?
“当试辑ֈ一定的E度后,试效益会呈现递减态势。”所以,你不要期望通过试扑և所有的bug Q而是要通过试Q找出绝大多数的 bug ?
q个地方其实也符合“二八定律”:?0% 的测试可以找?80% ?bug Q其余的 80% 的测试可以找出剩下的 20% ?bug 。我们要做的Q就是写q?20% 的测试,而非 100% 的测试?