做任何提炼前,先移除局部变量。将重复的行为也搬移到函数。将原函数分解成一组嵌套的函数。应用拆分,分离计算逻辑与输出格式化逻辑。为计算器引入多态性来处理计算逻辑。好代码的检验标准就是人们是否能轻而易举地修改它。因此改进设计的一个重要方向就是,消除重复代码,确定所有事物和行为在代码中只表述一次。三次法则:第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构。正如老话说的:事不过三,三则重构。我的项目计划上没有专门留给重构的时间,绝大多数重构都在我做其他事的过程中自然发生哪怕你完全了解系统,也请实际度量它的性能,不要臆测。臆测会让你学到一些东西,但十有八九你是错的。设计API时,可以使用将查询函数和修改函数分离。字符串是这种坏味道的最佳培养皿,比如,电话号码不只是一串字符。一个体面的类型,至少能包含一致的显示逻辑,在用户界面上需要显示时可以使用。任何switch语句都应该用以多态取代条件表达式消除掉。我们甚至还听过这样的观点:所有条件逻辑都应该用多态取代,绝大多数if语句都应该被扫进历史的垃圾桶。纯数据类常常意味着行为被放在了错误的地方。也就是说,只要把处理数据的行为从客户端搬移到纯数据类里来,就能使情况大为改观。不可修改的字段无须封装,使用者可以直接通过字段取得数据,无须通过取值函数。当你感觉需要撰写注释时,请先尝试重构,试着让所有注释都变得多余。总是确保测试不该通过时真的会失败。考虑可能出错的边界条件,把测试火力集中在那儿。对付循环, 我有两个常用的手法: 拆分循环可以确保每个循环只做一件事, 以管道取代循环则可以直接消灭整个循环。如果我看见代码从一个记录结构中导出几个值, 然后又把这几个值一起传递给一个函数, 我会更愿意把整个记录传给这个函数, 在函数体内部导出所需的值。函数下移:如果超类中的某个函数只与一个(或少数几个) 子类有关, 那么最好将其从超类中挪走, 放到真正关心它的子类中去。 这项重构手法只有在超类明确知道哪些子类需要这个函数时适用。 如果超类不知晓这个信息, 那我就得用以多态取代,只留些共用的行为在超类。