一.适用环境
有些函数,在各个子类(subclass)中产生完全相同的结果.
二.解决方案
将该函数移至父类(superclass).
三.动机
避免行为重复是重要的,因为重复很可能会成为错误的滋生地.只要系统内出现重复,就意味着你会面临修改一个却未能修改另一个的风险.
四.范例
在代码中,我们发现PreferredCustomer类和RegularCustomer 类中的creatBill()这个函数是一模一样的,所以我们就想到用Pull Up Method,也就是把这个函数上移到父类Customer当中去,
不过,这里不仅仅是移上去那么简单,我们仔细观察会发现:creatBill()函数中又调用了一个函数ComputeMoney(),并且这个函数只出现在子类里面,不在父类里面.所以在我们把creatBill()上移前,要作一些准备工作:
Martin Fowler重构一书中提供如下做法:
当待提升函数又调用了一个只出现在子类,未出现在父类的函数,你可以在父类中为被调用的函数声明一个抽象函数.
所以,我们只需在父类Customer中声明一个抽象函数public abstract double ComputeMoney(double Money) ,然后把待提升的函数Copy到父类,再把子类中的函数Delete就可以了.
五.作法
1.检查待提升函数,确定它们是完全一致的.
2.如果待提升函数的签名不同,将那些签名都修改为你想要在父类中使用的签名.
3.将待提升函数拷贝到父类中,并做适当调整.
当待提升函数又调用了一个只出现在子类,未出现在父类的函数,你可以在父类中为被调用的函数声明一个抽象函数.
4.逐一移除待提升的函数,直至只剩下父类中的函数为止.
5.观察该函数的调用者,看看是否可以将它所索求的对象型别改为父类.
有些函数,在各个子类(subclass)中产生完全相同的结果.
二.解决方案
将该函数移至父类(superclass).
三.动机
避免行为重复是重要的,因为重复很可能会成为错误的滋生地.只要系统内出现重复,就意味着你会面临修改一个却未能修改另一个的风险.
四.范例
CODE:
using System;
public class PreferredCustomer :Customer //贵宾顾客
{
public double ComputeMoney(double Money) //打折算法:贵宾打7折
{
return Money*0.7;
}
public void creatBill(double money) //创建帐单:输出打折后应付的金额
{
Console.WriteLine("你应该交纳的金额为"+ComputeMoney(money));
}
}
public class RegularCustomer :Customer //普通顾客
{
public double ComputeMoney(double Money) //打折算法:普通顾客不打折
{
return Money;
}
public void creatBill(double money) //创建帐单:输出打折后应付的金额
{
Console.WriteLine("你应该交纳的金额为"+ComputeMoney(money));
}
}
public class Customer //顾客
{
}
public class App
{
public static void Main()
{
PreferredCustomer rm=new PreferredCustomer (); //生成一个普通顾客
rm.creatBill(100); //他买了100元的东西,现在创建帐单,看他应该付多少钱
Console.ReadLine();
}
}
public class PreferredCustomer :Customer //贵宾顾客
{
public double ComputeMoney(double Money) //打折算法:贵宾打7折
{
return Money*0.7;
}
public void creatBill(double money) //创建帐单:输出打折后应付的金额
{
Console.WriteLine("你应该交纳的金额为"+ComputeMoney(money));
}
}
public class RegularCustomer :Customer //普通顾客
{
public double ComputeMoney(double Money) //打折算法:普通顾客不打折
{
return Money;
}
public void creatBill(double money) //创建帐单:输出打折后应付的金额
{
Console.WriteLine("你应该交纳的金额为"+ComputeMoney(money));
}
}
public class Customer //顾客
{
}
public class App
{
public static void Main()
{
PreferredCustomer rm=new PreferredCustomer (); //生成一个普通顾客
rm.creatBill(100); //他买了100元的东西,现在创建帐单,看他应该付多少钱
Console.ReadLine();
}
}
在代码中,我们发现PreferredCustomer类和RegularCustomer 类中的creatBill()这个函数是一模一样的,所以我们就想到用Pull Up Method,也就是把这个函数上移到父类Customer当中去,
不过,这里不仅仅是移上去那么简单,我们仔细观察会发现:creatBill()函数中又调用了一个函数ComputeMoney(),并且这个函数只出现在子类里面,不在父类里面.所以在我们把creatBill()上移前,要作一些准备工作:
Martin Fowler重构一书中提供如下做法:
当待提升函数又调用了一个只出现在子类,未出现在父类的函数,你可以在父类中为被调用的函数声明一个抽象函数.
所以,我们只需在父类Customer中声明一个抽象函数public abstract double ComputeMoney(double Money) ,然后把待提升的函数Copy到父类,再把子类中的函数Delete就可以了.
CODE:
public class PreferredCustomer :Customer //贵宾
{
public override double ComputeMoney(double Money)
{
return Money*0.7;
}
}
public class RegularCustomer :Customer //普通顾客
{
public override double ComputeMoney(double Money)
{
return Money;
}
}
public abstract class Customer //顾客
{
public abstract double ComputeMoney(double Money);
public void creatBill(double money) //此函数已被提升
{
Console.WriteLine("你应该交纳的金额为"+ComputeMoney(money));
}
}
{
public override double ComputeMoney(double Money)
{
return Money*0.7;
}
}
public class RegularCustomer :Customer //普通顾客
{
public override double ComputeMoney(double Money)
{
return Money;
}
}
public abstract class Customer //顾客
{
public abstract double ComputeMoney(double Money);
public void creatBill(double money) //此函数已被提升
{
Console.WriteLine("你应该交纳的金额为"+ComputeMoney(money));
}
}
五.作法
1.检查待提升函数,确定它们是完全一致的.
2.如果待提升函数的签名不同,将那些签名都修改为你想要在父类中使用的签名.
3.将待提升函数拷贝到父类中,并做适当调整.
当待提升函数又调用了一个只出现在子类,未出现在父类的函数,你可以在父类中为被调用的函数声明一个抽象函数.
4.逐一移除待提升的函数,直至只剩下父类中的函数为止.
5.观察该函数的调用者,看看是否可以将它所索求的对象型别改为父类.

添加至收藏夹