你的程序中,某个字段被其所驻类之外的另一个类更多的用到.在目标类建立一个新字段,修改源字段的所有用户,令它们改用新字段.        动机:在类之间移动状态和行为,是重构过程中必不可少的措施.随着系统发展,你会发现自己需要新的类,并需要将现有的工作责任拖到新的类中.在这个星期看似合理而正确的设计决策,到了下个星期可能不再正确.这没问题,如果你从来没遇到这种情况,那才有问题. 如果发现对于一个字段,在其所驻类之外的另一个类中有更多函数使用了它,就考虑搬移这个字段.上述所谓“使用”可能是通过设值/…
某个类没有做太多事情.将这个类的所有特性搬移到另一个类中,然后移除原类. 动机:Inline Class (将类内联化)正好于Extract Class (提炼类)相反.如果一个类不再承担足够责任.不再有单独存在的理由(这通常是因为此前的重构动作移走了这个类的责任),就挑选这个“萎缩类”的最频繁的用户(也是个类),以Inline Class (将类内联化)手法将“萎缩类”塞进另一个类中. 做法:1.在目标类身上声明源类的public协议,并将其中所有函数委托至源类.如果“以一个独立接口表示源类函…
重构手法16:Introduce Foreign Method (引入外加函数)你需要为提供服务的类增加一个函数,但你无法修改这个类.在客户类中建立一个函数,并以第一参数形式传入一个服务类实例. 动机:这种事情发生了太多次了,你正在使用一个类,它真的很好,为你提供了需要的所有服务.而后,你又需要一项新服务,这个类却无法供应.于是你开始咒骂“为什么不能做这件事?”如果可以修改源码,你便可以自行添加一个新函数:如果不能,你就得在客户端编码,补足你要的那个函数. 如果客户类只使用这项功能一次,那么额外…
你有一个大型函数,其中对局部变量的使用,使你无法釆用 Extract Method. 将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的值域(field) 然后你可以在同一个对象中将这个大型函数分解为数个小型函数. class Order... double price() { double primaryBasePrice; double secondaryBasePrice; double tertiaryBasePrice; // long computation; ... }…
代码对一个 参数赋值.以一个临时变量取代该参数的位置.     int Discount(int inputVal, int quantity, int yearTodate) { if (inputVal > 50) { inputVal -= 2; } } 重构后: int Discount(int inputVal, int quantity, int yearTodate) { int result=inputVal; if (inputVal > 50) { result -= 2;…
  发现:你有一个复杂的表达式. 解决:将该复杂的表达式(或其中的部分)的结果放进一个临时变量,并以此变量名称来解释表达式用途. //重构前 if((platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1) && wasInitialized() && resize > 0) {…
所谓的以查询取代临时变量:就是当你的程序以一个临时变量保存某一个表达式的运算效果.将这个表达式提炼到一个独立函数中.将这个临时变量的所有引用点替换为对新函数的调用.此后,新函数就可以被其他函数调用. 例子如下: double basePrice = _quantity*_itemPrice; if (basePrice > 1000) { return basePrice * 0.95; } else { return basePrice * 0.98; } 重构之后代码: if (BasePr…
Inline Method (内联函数) 一个函数调用的本体与名称同样清楚易懂.在函数调用点插入函数体,然后移除该函数. int GetRating() { return MoreThanfiveLateDeliverise() ? 2 : 1; } bool MoreThanfiveLateDeliverise() { return _numberOfLateLiveries > 5; } int GetRating() { return _numberOfLateLiveries > 5…
背景: 你有一段代码可以被组织在一起并独立出来.将这段代码放进一个独立函数,并让函数名称解释该函数的用途. void PrintOwing(double amount) { PrintBanner(); //print details Console.WriteLine("name:"+_name); Console.WriteLine("amount:"+_amount); } void PrintOwing(double amount) { PrintBanne…
你有一笔数据项(data item),需要额外的数据和行为. 将这笔数据项变成一个对象. class Order... private string customer; ==> class Order... private Customer _customer; class Customer... private string _name; 动机 一开始你可能会用一个字符串来表示[电话号码]概念,但是随后你就会发现,电话号码需要[格式化].[抽取区号]之类的特殊行为.当这些臭味开始出现,你就应该…