`
kuyuyingzi
  • 浏览: 54411 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

重构改善既有代码的设计-处理概括关系

 
阅读更多

有一批重构手法专门用来处理类的概括关系,即继承关系。其中主要是将函数上下移动于继承体系之中。

1、PullUpField(字段上移)

两个子类拥有相同的字段。将该字段移至超类。

2、PullUpMethod(函数上移)

有些函数,在各个类中产生完全相同的结果。将该函数移至超类。

3、PullUpConstructorBody(构造函数本体上移)

你在各个子类中拥有一些构造函数,它们本体几乎完全一致。在超类中新建一个构造函数,并在子类构造函数中调用它。

代码1

classManagerextendsEmployee...

publicManager(Stringname,Stringid,intgrade){

_name=name;

_id=id;

_grade=grade;

}

代码2

publicManager(Stringname,Stringid,intgrade){

super(name,id);

_grade=grade;

}

4、PushDownMethod(函数下移)

超类中的某个函数只与部分(而非全部)子类有关。将这个函数移到相关的那些子类去。

5、PushDownField(字段下移)

超类中的某个字段只被部分(而非全部)子类用到。将这个字段移到需要它的那些子类去。

6、ExtractSubclass(提炼子类)

类中的某些特性只被某些(而非全部)实例用到。新建一个子类,将上面所说的那一部分特性移到子类中。

7、ExtractSuperclass(提炼超类)

两个类有相似特性。为这两个类建立一个超类,将相同特性移至超类。

8、ExtractInterface(提炼接口)

若干客户使用类接口中的同一子集,或者两个类的接口有部分相同。将相同的子集提炼到一个独立接口中。

9、CollapseHierarchy(折叠继承体系)

10、FormTemplateMethod(塑造模板函数)

动机:你有一些子类,其中相应的某些函数以相同顺序执行类似的操作,但各个操作的细节上有所不同。

做法:将这些操作分别放进独立函数中,并保持它们都有相同的签名,于是原函数也就变得相同。然后将原函数上移至超类。

代码1

class Customer {
 
public String statement(){
return new TextStatement().value(this);
}
public String htmlStatement(){
return new HtmlStatement().value(this);
}
}
 
class TextStatement{
public String value(Customer aCustomer){
Enumeration<e> rentals = aCustomer.getRentals();
String result = "Rental Record for " + aCustomer.getName() + "\n";
while(rentals.hasMoreElements()){
Rental each = (Rental) rentals.nextElement();
//show figures for this rental
result += "\t" + each.getMovie().getTitle() + "\t"
+ String.valueOf(each.getCharge()) + "\n";
}
//add footer lines
result += "Amount owed is "
+ String.valueOf(aCustomer.getTotalCharge()) + "\n";
result += "You earned "
+ String.valueOf(aCustomer.getTotalFrequentRenterPoints())
+ " frequent renter points";
return result;
}
}
 
class HtmlStatement {
public String value(Customer aCustomer){
Enumeration<e> rentals = aCustomer.getRentals();
String result = "<H1>Rental Record for <EM>" + aCustomer.getName()
+ "</EM></H1><P>\n";
while(rentals.hasMoreElements()){
Rental each = (Rental) rentals.nextElement();
//show figures for this rental
result += each.getMovie().getTitle() + ":"
+ String.valueOf(each.getCharge()) + "<BR>\n";
}
//add footer lines
result += "<P>You owed <EM>"
+ String.valueOf(aCustomer.getTotalCharge()) + "</EM><P>\n";
result += "On this rental you earned <EM> "
+ String.valueOf(aCustomer.getTotalFrequentRenterPoints())
+ "</EM> frequent renter points<P>";
return result;
}
}

代码2:将上面两个类中不同的地方抽出来,分别放进独立函数中。

class TextStatement{
String headerString(Customer aCustomer){
return "Rental Record for " + aCustomer.getName() + "\n";
}
String eachRentalString(Rental aRental){
return "\t" + aRental.getMovie().getTitle() + "\t"
+ String.valueOf(aRental.getCharge()) + "\n";
}
String footerString(Customer aCustomer){
return "Amount owed is "
+ String.valueOf(aCustomer.getTotalCharge()) + "\n"
+"You earned "
+ String.valueOf(aCustomer.getTotalFrequentRenterPoints())
+ " frequent renter points";
}
public String value(Customer aCustomer){
Enumeration<e> rentals = aCustomer.getRentals();
String result = headerString(aCustomer);
while(rentals.hasMoreElements()){
Rental each = (Rental) rentals.nextElement();
//show figures for this rental
result += eachRentalString(each);
}
//add footer lines
result += footerString(aCustomer);
return result;
}
}
 
class HtmlStatement {
String headerString(Customer aCustomer){
return "<H1>Rental Record for <EM>" + aCustomer.getName()
+ "</EM></H1><P>\n";
}
String eachRentalString(Rental aRental){
return aRental.getMovie().getTitle() + ":"
+ String.valueOf(aRental.getCharge()) + "<BR>\n";
}
String footerString(Customer aCustomer){
return "<P>You owed <EM>"
+ String.valueOf(aCustomer.getTotalCharge()) + "</EM><P>\n"
+ "On this rental you earned <EM> "
+ String.valueOf(aCustomer.getTotalFrequentRenterPoints())
+ "</EM> frequent renter points<P>";
}
public String value(Customer aCustomer){
Enumeration<e> rentals = aCustomer.getRentals();
String result = headerString(aCustomer);
while(rentals.hasMoreElements()){
Rental each = (Rental) rentals.nextElement();
//show figures for this rental
result += eachRentalString(each);
}
//add footer lines
result += footerString(aCustomer);
return result;
}
}

代码3:经过第二步处理,我们将相同的函数提炼到超类中。函数内容不同提炼为抽象类。

abstract class Statement{
abstract String headerString(Customer aCustomer);
abstract String eachRentalString(Rental aRental);
abstract String footerString(Customer aCustomer);
public String value(Customer aCustomer){
Enumeration<e> rentals = aCustomer.getRentals();
String result = headerString(aCustomer);
while(rentals.hasMoreElements()){
Rental each = (Rental) rentals.nextElement();
//show figures for this rental
result += eachRentalString(each);
}
//add footer lines
result += footerString(aCustomer);
return result;
}
}


第四步:TextStatement、HtmlStatement继承Statement,并实现抽象函数。

11、ReplaceInheritancewithDelegation(以委托取代继承)

动机:某个子类只使用接口中的一部分,或是根本不需要继承而来的数据。

代码1:只要看看MyStack的用户,我就会发现,用户只要它做4件事:push()pop()size()isEmpty()。后两个函数就是从Vector继承来的。

classMyStackextendsVector{

publicvoidpush(Objectelement){

insertElementAt(element,0);

}

publicObjectpop(){

Objectresult=firstElement();

removeElementAt(0);

returnresult;

}

}

代码2:跟封装模式有点类似,只不过只封装了需要用到的函数。

classMyStack{

privateVector_vector=newVector();

publicvoidpush(Objectelement){

_vector.insertElementAt(element,0);

}

publicObjectpop(){

Objectresult=_vector.firstElement();

_vector.removeElementAt(0);

returnresult;

}

publicintsize(){

return_vector.size();

}

publicbooleanisEmpty(){

return_vector.isEmpty();

}

}

12、ReplaceDelegationwithInheritance(以继承取代委托)

动机:需要用到受委托类的所有函数。

分享到:
评论

相关推荐

    重构-改善既有代码的设计 中文版.pdf

    第11章 处理概括关系 11.1 Pull Up Field(值域上移) 11.2 Pull Up Method(函数上移) 11.3 Pull Up Co tructor Body(构造函数本体上移) 11.4 Push Down Method(函数下移) 11.5 Push Down Field(值域下移) ...

    重构-改善既有代码的设计

    第11章 处理概括关系 319 11.1 Pull Up Field(字段上移) 320 11.2 Pull Up Method(函数上移) 322 11.3 Pull Up Constructor Body(构造函数本体上移) 325 11.4 Push Down Method(函数下移) 328 ...

    重构:改善既有代码的设计(中文高清版)

    第11章 处理概括关系319 11.1 PullUpField(字段上移)320 11.2 PullUpMethod(函数上移)322 11.3 PullUpConstructorBody(构造函数本体上移)325 11.4 PushDownMethod(函数下移)328 11.5 PushDownField(字段...

    重构_改善既有代码的设计[高清版]【已进行内容识别处理,可搜索,可编辑+有目录】

    2.6 重构与设计······ ·· · · ······· ·· ···· · ··· ·· · · ··· ·· ·· ····· · · · ·· ·· ·· ··· ·· ·· · ·· ·· ···· · ···· · · ·...

    重构-改善既有代码的设计 中文版

    第11章 处理概括关系 11.1 Pull Up Field(值域上移) 11.2 Pull Up Method(函数上移) 11.3 Pull Up Co tructor Body(构造函数本体上移) 11.4 Push Down Method(函数下移) 11.5 Push Down Field(值域下移) ...

    重构:改善既有代码的设计(中文版).

    第11章 处理概括关系319 11.1 PullUpField(字段上移)320 11.2 PullUpMethod(函数上移)322 11.3 PullUpConstructorBody(构造函数本体上移)325 11.4 PushDownMethod(函数下移)328 11.5 PushDownField(字段...

    程序员该读的十本好书之《重构改善既有代码的设计》

    按照传统,书籍应该以一个简介开头口尽管我也同意这个原则,但是我发现以概括性的讨论或定义来介绍重构,实在不是件容易的事。所以我决定拿一个实例做为开路先锋。 第1章展示一个小程序,其中有些常见的设汁缺陷,...

    重构_改善既有代码的设计.pdf

    第11章 处理概括关系319 11.1 PullUpField(字段上移)320 11.2 PullUpMethod(函数上移)322 11.3 PullUpConstructorBody(构造函数本体上移)325 11.4 PushDownMethod(函数下移)328 11.5 PushDownField(字段...

    重构-改善既有代码的设计(chm清晰版)

    作者:Martin Fowler,Kent Beck,John Brant ,William Opdyke ,Don Roberts 翻译:侯捷、熊节 ...章节十一 处理概括关系 章节十二 大型重构 章节十三 重构,复用与现实 章节十四 重构工具 章节十五 集成

    重建——改善既有代码的设计

    第11章 处理概括关系319 11.1 PullUpField(字段上移)320 11.2 PullUpMethod(函数上移)322 11.3 PullUpConstructorBody(构造函数本体上移)325 11.4 PushDownMethod(函数下移)328 11.5 PushDownField(字段...

    重构:改善既有代码的设计.[美]Martin Fowler.epub【文字版手机格式】

    重构,一言以蔽之,就是在不改变外部行为的前提下,有条不紊地改善代码。多年前,正是本书原版的出版,使重构终于从编程高手们的小圈子走出,成为众多普通程序员日常开发工作中不可或缺的一部分。本书也因此成为与...

    重构_改善既有代码的设计

    第 11 章:处理概括关系(Dealing with Generalization) 第 12 章:大型重构(Big Refactorings, by Kent Beck and Martin Fowler) 第 13 章:重构、复用与现实 第 14 章:重构工具(Refactoring Tools, ...

    重构—改善既有代码的设计

    1、重构起源、概述 ...6、6处理概括关系(DealingwithGeneralization) 7、大型重构(BigRefactorings) 8、重构、复用、与现实(Refactoring,Reuse,andReality) 9、重构工具(RefactoringTools)

    《重构改善既有代码的设计(2010年版)》(Martin Fowler[美] 著,熊节 译)

    重构,一言以蔽之,就是在不改变外部行为的前提下,有条不紊地改善代码。多年前,正是本书原版的出版,使重构终于从编程高手们的小圈子走出,成为众多普通程序员日常开发工作中不可或缺的一部分。本书也因此成为与...

Global site tag (gtag.js) - Google Analytics