重构方法及设计思路

上传人:zhu****ng 文档编号:157031168 上传时间:2022-09-28 格式:DOCX 页数:43 大小:83.59KB
收藏 版权申诉 举报 下载
重构方法及设计思路_第1页
第1页 / 共43页
重构方法及设计思路_第2页
第2页 / 共43页
重构方法及设计思路_第3页
第3页 / 共43页
资源描述:

《重构方法及设计思路》由会员分享,可在线阅读,更多相关《重构方法及设计思路(43页珍藏版)》请在装配图网上搜索。

1、重构方法(1) - 提取方法描述:当你的代码中有一些片段在逻辑上能够归为一组,那么通常可以将这一组代码提取出来形成一个方法,并用方法名来解释方法的目的。动机:1. 提高了其他方法重用这段代码的可能性。2. 使得高层的方法可读性更好。3. 当有需要的时候,重载更加方便。步骤:1. 创建一个新方法,以方法的目的为该方法命名(而不是以方法的具体行为为该方法命名)。2. 把要提取的方法从原来的方法中拷贝到新方法中。3. 检查提取的代码,看看其中是否有对原来方法中的局部变量的引用(通常IDE会帮我们做,会用编译错误来提示找不到变量)。如果有,将该变量作为方法的参数。4. 检查在原方法中是否有只在提取的代

2、码中使用的临时变量,如果有,将该变量移入提取的方法中。5. 看看在第三步中的局部变量在方法中是否被改变了。如果只有一个局部变量被改变,那么我们可以将该变量作为方法的返回值返回。如果有多于一个的变量被改变,那么我们可能需要先进行分离临时变量(另外一种重构方法,以后介绍)重构,再进行提取方法的重构。我们以可以使用使用查询方法代替临时变量(另外一种重构方法,以后介绍)来减少临时变量的个数。6. 编译代码,看看是否有错误。7. 用提取的方法替换原来方法中被提取的代码。注意在原方法中删除第四步中我们移入的临时变量。8. 编译,运行单元测试。例子:1.没有局部变量的情况1. void printOwing

3、()2. Enumeration e = _orders.elements();3. double outstanding = 0.0;4.5.6.7. /打印提示信息8. System.out.println(“*”);9. System.out.println(“* Customer10. Owes *”);11. System.out.println(“*”);12.13.14.15. /计算应付金额16. while (e.hasMoreElements() 17. Order each = (Order) e.nextElement();18. outstanding+= each.

4、getAmount();19. 20.21.22.23. /打印详细信息24. System.out.println(“name:” +25. _name);26. System.out.println(“amount:” +27. outstanding);28. 复制代码在这里,我们可以很容易的将打印提示信息的部分代码提取成单独的方法。1. void printOwing()2. Enumeration e = _orders.elements();3. double outstanding = 0.0;4.5.6.7. printBanner();8.9.10.11. /计算应付金额12

5、. while (e.hasMoreElements() 13. Order each = (Order) e.nextElement();14. outstanding+= each.getAmount();15. 16.17.18.19. /打印详细信息20. System.out.println(“name:” +21. _name);22. System.out.println(“amount:” +23. outstanding);24. 25.26.27.28. void printBanner()29. System.out.println(“*”);30. System.out

6、.println(“*31. Customer Owes *”);32. System.out.println(“*”);33. 复制代码2.提取代码中读取局部变量的情况还是使用上面的代码,我们来提取打印详细信息的方法。1. void printOwing()2. Enumeration e = _orders.elements();3. double outstanding = 0.0;4.5.6.7. printBanner();8.9.10.11. /计算应付金额12. while (e.hasMoreElements() 13. Order each = (Order) e.nextE

7、lement();14. outstanding+= each.getAmount();15. 16.17.18.19. printDetail(outstanding);20. 21.22.23.24. void25. printBanner()26. System.out.println(“*”);27. System.out.println(“*28. Customer Owes *”);29. System.out.println(“*”);30. 31.32.33.34. void35. printDetail(double outstanding)36. System.out.pr

8、intln(“name:” +37. _name);38. System.out.println(“amount:”39. + outstanding);40. 复制代码可以看到,我们将在提取的代码中要读取的局部变量作为方法的参数传入。3. 局部变量重新赋值的情况下面我们来看看提取计算应付金额的方法。由于这段代码中对局部变量outstanding进行了重新赋值,因此提取后的结果如下:1. void printOwing()2. printBanner();3. double outstanding = getOutstanding();4. printDetail(outstanding);5

9、. 6.7. void printBanner()8. System.out.println(“*”);9. System.out.println(“* Customer Owes *”);10. System.out.println(“*”);11. 12.13. void printDetail(double outstanding)14. System.out.println(“name:” + _name);15. System.out.println(“amount:” + outstanding);16. 17.18. double getOutstanding()19. Enum

10、eration e = _orders.elements();20. double result = 0.0;21.22. while (e.hasMoreElements() 23. Order each = (Order) e.nextElement();24. result+= each.getAmount();25. 26.27. return result;28. 复制代码可以看到,被重新赋值的局部变量作为返回值返回了软件改进 重构方法(2) - 内联方法描述:如果方法的内容很简短并且非常容易理解,我们可以在调用该方法的语句中直接使用方法体的内容,这样可以移除这个方法。动机:重构的一

11、个主题就是使用方法名来表明方法的功能,这样可以带来更加清晰易读的代码。但是如果方法体和方法名一样清晰易懂,这个时候使用方法就不必要了。另外一个使用内联方法重构的时机是当我们有一组构建的很差的方法需要进行重构,我们可以将所有的方法体都放到原来的大的方法中,然后在使用提取方法来重构代码。如果已有的代码中使用了他多的间接层,并且很多方法只是简单的代理另一个方法,这个时候我们可以使用内联方法重构来消除不必要的间接层。步骤:1.检查方法不是多态的。如果子类重写并覆盖了该方法,就不能使用内联方法来重构,因为子类不能覆盖不存在的方法。2.查找所有调用该方法的地方。3.将所有的调用都使用方法体替换。4.编译并

12、测试。5.移除原来的方法。例子: 1. int getRating()2. return (moreThanFiveLateDeliveries()?2:1;3. 4.5. boolean moreThanFiveLateDeliveries()6. return _numberOfLateDeliveries 5;7. 复制代码可以重构为: 1. int getRating()2. return (_numberOfLateDeliveries 5)?2:1;3. 复制代码软件改进 重构方法(3)- 用查询方法代替临时变量描述:在程序中我们经常使用临时变量来保存一个表达式的值。这个重构要做的

13、就是将该表达式提取到一个方法中,然后将所有对该临时变量的引用用该方法替代。动机:临时变量是临时的而且是局部的,只能在当前方法中可见。这样一来,使用临时变量通常会导致开发人员编写很长的方法。因为临时变量只在该方法中可见,因此开发人员会将所有访问该临时变量的代码都放在同一个方法中。另外,在使用提取方法来重构之前,通常也会使用本方法,因为局部变量通常会使得提取方法重构变得困难。如果该临时变量只被赋值了一次,那么这个重构就比较简单。如果该临时变量被赋值了多次,我们可能需要先使用分离临时变量(另外一种重构方法,以后会介绍)。步骤:1.将该临时变量定义为final的,编译。如果临时变量被再次赋值了,编译就

14、会报错。这样可以确保临时变量只赋值了一次。2.将该临时变量赋值语句的右边提取到一个方法中。将临时变量赋值语句的右边用该方法替换。编译并测试。3.将所有对该临时变量的引用用方法来代替。删除临时变量的定义。编译并测试。例子:假如我们有如下的代码: 1. double getPrice() 2. int basePrice = _quantity * _itemPrice;3. double discountFactor;4. if (basePrice 1000) discountFactor = 0.95;5. else discountFactor = 0.98;6. return baseP

15、rice * discountFactor;7. 复制代码首先,我们将basePrice和discountFactor定义为final的。 1. double getPrice() 2. final int basePrice = _quantity * _itemPrice;3. final double discountFactor;4. if (basePrice 1000) discountFactor = 0.95;5. else discountFactor = 0.98;6. return basePrice * discountFactor;7. 复制代码然后,我们将baseP

16、rice赋值语句的右边提取到方法中,并使用该方法替换赋值语句的右边。 1. double getPrice() 2. final int basePrice = getBasePrice();3. final double discountFactor;4. if (basePrice 1000) discountFactor = 0.95;5. else discountFactor = 0.98;6. return basePrice * discountFactor;7. 8.9. private getBasePrice()10. return _quantity * _itemPri

17、ce;11. 复制代码然后,我们将所有对basePrice的引用都替换为getBasePrice,并删除basePrice的声明。 1. double getPrice() 2. final double discountFactor;3. if (getBasePrice() 1000) discountFactor = 0.95;4. else discountFactor = 0.98;5. return getBasePrice() * discountFactor;6. 7.8. private getBasePrice()9. return _quantity * _itemPri

18、ce;10. 复制代码我们可以对discountFactor采用同样的步骤,最后得到的代码是: 1. double getPrice() 2. return getBasePrice() * getDiscountFactor();3. 4.5. private getBasePrice()6. return _quantity * _itemPrice;7. 8.9. private getDiscountFactor()10. if (getBasePrice() 1000)11. return 0.95;12. else 13. return 0.98;14. 复制代码其他:有一个疑问是

19、这样会不会带来性能问题,毕竟原来只需要计算一次的表达式在重构后可能要计算多次。Martin Fowler给出的回答是:暂时不要考虑这些。根据他的经验,十有八九这不是什么问题。如果真的有性能问题,在最后性能调优的时候再来解决。如果我们有组织的很好的代码,在最终性能调优的时候,多半能够找到更好的优化方案。最好的情况是我们把这些临时变量再恢复过来,这也不是多么困难的事情。软件改进 重构方法(4) - 引入解释性变量描述:如果有一个很复杂的表达式,比较难以理解。我们可以将其中的一部分的结果放在临时变量中,给临时变量起一个有意义的名字。动机:如果表达式过于复杂,可读性会很差,难以理解。在这种情况下,将表

20、达式拆分成多个部分,给每个部分按照其目的起个有意义的名字,这样可以增加可读性。步骤:1.声明一个临时变量,将表达式的一部分赋予该临时变量。2.将原表达式中相应的部分使用临时变量替换。编译并测试。3.将同样的步骤应用于表达式的其他部分。例子:原始代码 1. double getTotalPrice()2. return _quantity * _itemPrice Math.max(0, _quantity-500) * _itemPrice * 0.05 3. + Math.min(_quantity * _itemPrice * 0.1, 100);4. 复制代码这段表达式的逻辑是:总价 =

21、 数量 单价 数量折扣(超过500个以上的部分打95折)+ 运费(运费为价格的10%,最高100元)。首先我们声明临时变量: 1. double getTotalPrice()2. final double basePrice = _quantity * _itemPrice;3.4. return _quantity * _itemPrice Math.max(0, _quantity-500) * _itemPrice * 0.05 5. + Math.min(_quantity * _itemPrice * 0.1, 100);6. 复制代码然后用临时变量替换表达式中相应的部分: 1.

22、double getTotalPrice()2. final double basePrice = _quantity * _itemPrice;3.4. return basePrice Math.max(0, _quantity-500) * _itemPrice * 0.05 5. + Math.min( basePrice * 0.1, 100);6. 复制代码将相同的步骤应用于其他部分,最后得到 1. double getTotalPrice()2. final double basePrice = _quantity * _itemPrice;3. final double qua

23、ntityDiscount = Math.max(0, _quantity-500)*_itemPrice*0.05;4. final double shipping = Math.min(basePrice *0.1, 100);5.6. return basePrice quantityDiscount + shipping; 7. 复制代码其他:在上一个方法用查询方法代替临时变量中,我们的目的是尽量避免临时变量的使用。因此在这个例子中,我们可以使用提取方法来重构。具体的过程就不讲了,最后的到的结果是: 1. double getTotalPrice()2. return getBaseP

24、rice() getQuantityDiscount() +getShipping(); 3. 4.5. private double getBasePrice()6. return _quantity * _itemPrice;7. 8.9. private double getQuantityDiscount()10. return Math.max(0, _quantity-500)*_itemPrice*0.05;11. 12.13. private double getShipping()14. return Math.min(getBasePrice() *0.1, 100);15

25、. 复制代码通常情况下我们推荐使用提取方法来重构。如果采用提取方法有困难,那么再使用引入解释性变量来重构。软件改进 重构方法(5) - 分离临时变量描述:有一个临时变量被多次赋值,而且该临时变量既不是一个循环变量【1】也不是一个求和的变量【2】。这种情况下,我们应该考虑分离临时变量。动机:临时变量通常用来保存将来还要使用的值,临时变量通常只应该被赋值一次。如果一个临时变量被赋值了多次,说明该临时变量在该方法中承担了多个责任。如果一个临时变量承担了多个责任会使得代码难以阅读。在这种情况下,我们应该按照责任将临时变量分离为多个临时变量。步骤:1.在变量的声明和第一次赋值的语句中,改变变量的名字。2

26、.将变量定义为final的。3.逐个改变对变量的引用,使用新的名称,直到变量再次被赋值为止。4.在变量再次被赋值的地方定义新的变量。5.重复步骤1-4,直到所有变量的引用都被修改完毕。6.编译并测试。例子:假设我们有一个物体质量为_mass。该物体从静止开始,收到第一个力(_primaryForce)的作用。经过一段时间(_delay)之后, 另外一个同方向的力(_secondaryForce)也作用在该物体上。根据物理定律,我可以计算某段时间之后物体移动的距离。下面的代码就是计算该距离的:原始代码: 1. double getDistanceTravelled(int time)2. dou

27、ble result;3. double acc=_primaryForce/_mass;4. int primaryTime = Math.min(time, _delay);5. result = 0.5 * acc * primaryTime * primaryTime;6. int secondaryTime = time - _delay;7. if (secondaryTime 0) 8. double primaryVel = acc * _delay;9. acc = (_primaryForce + _secondaryForce)/_mass;10. result += p

28、rimaryVel * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime;11. 12. return result;13. 复制代码在这段代码中,临时变量acc被赋值了两次,也就是说它承担了两个责任。第一个责任是保存仅仅有第一个力作用的时候的加速度;第二个责任是保存有两个力作用的时候的加速度。因此我们可以将其分离成两个临时变量。首先,我们修改acc的声明和第二次赋值之前的引用。 1. double getDistanceTravelled(int time)2. double result;3. doubleprimaryAc

29、c=_primaryForce/_mass;4. int primaryTime = Math.min(time, _delay);5. result = 0.5 * primaryAcc * primaryTime * primaryTime;6. int secondaryTime = time - _delay;7. if (secondaryTime 0) 8. double primaryVel = primaryAcc * _delay;9. acc = (_primaryForce + _secondaryForce)/_mass;10. result += primaryVel

30、 * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime;11. 12. return result;13. 复制代码然后,在第二次赋值的地方添加新的临时变量的声明,并修改后面的引用。 1. double getDistanceTravelled(int time)2. double result;3. doubleprimaryAcc=_primaryForce/_mass;4. int primaryTime = Math.min(time, _delay);5. result = 0.5 * primaryAcc * pri

31、maryTime * primaryTime;6. int secondaryTime = time - _delay;7. if (secondaryTime 0) 8. double primaryVel = primaryAcc * _delay;9. int secondaryAcc = (_primaryForce + _secondaryForce)/_mass;10. result += primaryVel * secondaryTime + 0.5 * secondaryAcc * secondaryTime * secondaryTime;11. 12. return re

32、sult;13. 复制代码其他:【1】:循环变量是指用于控制循环的变量,如for(int i=0; i 50) inputValue -= -2;3. if (quantity100) inputValue -=1;4. if (yearToDate 10000) inputValue -= 4;5. return inputValue;6. 复制代码重构后的代码: 1. int discount (int inputValue, int quantity, int yearToDate)2. int result = inputValue;3. if (inputValue 50) resu

33、lt -= -2;4. if (quantity100) result -=1;5. if (yearToDate 10000) result -= 4;6. return result;7. 复制代码如果要确保参数没有被重新赋值,我们可以给参数加上final修饰,如 1. int discount (final int inputValue, final int quantity, final int yearToDate)2. .3. 复制代码软件改进 重构方法(7) - 用方法对象代替方法描述:如果有一个很长的方法,但是由于局部变量的使用,我们没有办法使用提取方法来重构,在这种情况下可以

34、使用本重构方法。我们可以将创建一个新的对象,然后将该方法放到新的对象中,将所有的局部变量转变为新对象的成员变量。然后在新对象中使用提取方法来重构。动机:太长的方法是代码异味之一,这样的方法一般难以阅读和修改。如果因为局部变量的使用使得我们无法用提取方法来将长的方法拆分为多个小的方法,我们可以使用这个重构来将局部变量转换为新类的成员变量,这样就可以将提取方法重构应用在新的类上。做法:1.创建一个新类,以该方法的含义来命名该类。2.为该新类定义一个final类型的成员变量来保存原来的对象,为该方法中的每个局部变量和参数在新类中创建一个成员变量。3.为新类创建一个构造函数,该函数接受原来的对象和原来

35、方法中的参数作为参数。4.在新类中创建一个名为compute的方法。5.将原来方法的内容全部拷贝到新的compute方法中。将方法中所有对原来类中的方法的调用修改为对第2步中创建的final类型的成员变量的方法的调用。6.编译。7.修改原来的方法为:创建新类的实例,调用新创建的方法。现在在新创建的类中,所有的局部变量都转变成了类的成员变量,我们可以很容易的使用提取方法来重构了。例子:一时半会找不到很合适的例子,我们就使用以下的例子来演示一下重构的过程。(下面例子中的原来的代码可能不需要重构,我们只是借以说明一下。)原来的代码:(Class Account) 1. int gamma(int i

36、nputVal, int quantity, int yearToDate)2. int importantValue1 = (inputVal * quantity) detla();3. int importantValue2 = (inputVal * yearToDate) -+ 100;4. if (yearToDate importantValue1 100)5. importantValue2 -= 20;6. int imporatnatValue3 = importantValue2 * 7;7. .8. return importantValue3 2 * importan

37、tValue1;9. 复制代码首先我们创建一个新的类Gamma,在该类中定义相应的成员变量。Class Gamma: 1. private final Account _account;2. private int inputVal;3. private int quantity;4. private int yearToDate;5. private int importValue1;6. private int importValue2;7. private int importValue3;复制代码然后创建如下的构造函数: 1. public Gamma(Account source,

38、int inputValArg, int quantityArg, int yearToDateArg)2. _account = source;3. inputVal = inputValArg;4. quantity = quantityArg;5. yearToDate = yearToDateArg;6. 复制代码下面将原来的方法中的所有内容新的类的compute方法中,修改对原来类中方法的调用: 1. int compute()2. importantValue1 = (inputVal * quantity) account.detla();3. importantValue2 =

39、 (inputVal * yearToDate) + 100;4. if (yearToDate importantValue1 100)5. importantValue2 -= 20;6. imporatnatValue3 = importantValue2 * 7;7. .8. return importantValue3 2 * importantValue1;9. 复制代码最后,修改原来的方法:Class Account: 1. int gamma(int inputVal, int quantity, int yearToDate)2. return new Gama(this,

40、inputVal, quantity, yearToDate).compute();3. 复制代码软件改进 重构方法(8) - 移动方法描述:如果我们发现一个方法放到另外一个类中更加合适,我们可以采用本重构方法来将方法从一个类移动到另外一个类。动机:有时候我们会发现一个类承担了不应该属于该类的责任,我们需要将类中的某些方法移动到另外的类中(可能是一个新创建的类)。通常情况下,如果A类中的某个方法引用了B类中的很多变量或方法(比引用A类中的变量或方法还多),我们就可以考虑是否应该将该方法放到B类中。步骤:1.检查该方法引用的A类中的变量或者方法,看看这些变量或方法是否也应该移动到B类中。如果该变

41、量或者方法只被这个方法引用,我们就应该将它们一起移动到B类中。2.检查在A类的父类或子类中是否也定义了该方法。如果是,一般情况下我们无法移动该方法,除非在B类中也能实现这样的多态的情况。3.在b类中定义一个方法(可以是同名或不同名)。4.将原来方法的内容拷贝到新的方法中。如果方法中引用了A类的方法或成员变量,我们要决定怎样获得A类的引用。可以在B类中创建一个成员变量来引用A类,也可以在该方法中添加一个A类的参数。同时,如果原来的代码中会抛出异常,我们要决定异常是由A类来处理还是B类来处理。5.编译。6.决定在A类中怎样引用B类。(使用已有的成员变量?直接创建新实例?创建新的成员变量?)7.修改

42、原来的A类中的方法,该方法直接调用B类中的新方法。8.编译并测试。9.决定是否保留A类中的方法。如果保留,那么A类中的方法就是B类中的新方法的代理。如果不保留,那么需要修改代码中所有对A类中方法的调用,使他们调用B类中的新方法。10.编译并测试。例子:原始代码:class Account: 1. private AccountType _type;2. private int _daysOverdrawn;3.4. double overdraftCharge()5. if (_type.isPremium()6. double result = 10;7. if (_daysOverdraw

43、n 7) 8. result += (_daysOverdrawn -7) * 0.85;9. return result;10. else 11. return _daysOverdrawn * 1.75;12. 13. 14.15. double bankCharge()16. double result = 4.5;17. if (_daysOverdrawn 0) result += overdraftCharge();18. return result;19. 复制代码假如我们有多种账户类型,每种类型都有可能会有各自的计算overdraftCharge的方法。因此我们要将overdr

44、aftCharge方法移到AcocuntType类中。首先,overdraftCharge方法引用了_daysOverdrawn属性,这里我们不移动它。第二步,在AccountType中,定义新的方法,并将原方法的内容拷贝过去。然后调整对各个成员变量和方法的引用。class AccountType: 1. double overdraftCharge(int daysOverdrawn)2. if (isPremium() 3. double result = 10;4. if (daysOverdrawn 7) 5. result +=(daysOverdrawn 7)*0.85;6. re

45、turn result;7. else 8. return daysOverdrawn * 1.75);9. 10. 复制代码这里我们将daysOverdrawn作为方法的参数传递进来。(如果需要,也可以选择将Account对象作为参数传递进来)。编译程序,看看有没有什么错误。修改原来的类中的方法,将其变为新方法的一个代理。 1. class Account:2. double overdraftCharge()3. return _type.overdraftCharge(daysOverdrawn);4. 复制代码编译并测试代码。我们决定将原来类中的方法删除,那么我们就要将所有的调用改为对

46、AccountType类中的方法的调用。如: 1. class Account:2. double bankCharge()3. double result = 4.5;4. if (_daysOverdrawn 0) result += _type.overdraftCharge();5. return result;6. 复制代码当所有的对原来的方法的调用都修改了之后,就可以删除原来的方法,然后编译和测试。软件改进 重构方法(9) - 移动字段描述:如果一个字段放在另外一个类中比放在当前类中更加合适,我们就需要用这个方法来重构代码。动机:随着时间的改变,当初正确的设计现在看来可能不是那么合

47、适。我们可能需要创建新的类,或者改变某些类的职责。在这种情况下,我们可能需要将一个类中的字段移动到另外一个类中。总之,当我们发现这个字段放在另外一个类中更好的时候,就可以采用移动字段来重构。步骤:1.如果字段是public的,首先采用封装字段方法来重构(该方法以后会介绍,简单的说就是将public该为private,然后创建public的getter和setter方法。)。2.编译并测试。3.在目标类中创建同样的字段,并且有public的getter和setter方法。4.编译目标类。5.决定怎样来引用目标类。最好的情况是已经有了对目标类的引用,否则我们需要创建新的引用。6.移除原来类中的该字

48、段。7.将所有对原来类中该字段的引用转换为对目的类中相应方法的引用。8.编译并测试。例子:原来代码:class Account: 1. private double _interestRate;2.3. public void setInterestRate(double arg)4. _interestRate = arg;5. 6.7. public double getInterestRate()8. return _interestRate;9. 复制代码我们要将该字段移动到AccountType中去。class AccountType: 1. private double _inte

49、restRate;2.3. public void setInterestRate(double arg)4. _interestRate = arg;5. 6.7. public double getInterestRate()8. return _interestRate;9. 复制代码编译之后,我们删除Account类中的该字段,然后将所有对该字段的引用指向AccountType类中的字段。我们将下面的代码class Account: 1. public double interestForAmount_Days (double amount, int days)2. return ge

50、tInterestRate() * amount * days / 365;3. 复制代码修改为class Account: 1. public double interestForAmount_Days (double amount, int days)2. return _type.getInterestRate() * amount * days / 365;3. 复制代码如果Account中有许多地方都引用了该字段,我们也可以采用代理的方法,保留Account中的getter和setter方法,只是将它们代理到AccountType的相应方法。class Account: 1. pub

51、lic void setInterestRate(double arg)2. _type.setInterestRate(arg);3. 4.5. public double getInterestRate()6. return _type.getInterestRate();7. 复制代码软件改进 重构方法(10) - 提取类描述:有一个类实际上做了两个类的事情,我们需要将其中的一部分提取出来组成一个新的类。动机:一个类之应该完成一组相关的事情。在实际的代码开发中,类通常是不断的变大的,我们今天要添加一点东西,为这一点点东西创建一个新的类似乎不值得,于是添加到这个类中。明天又添加一点东西。日

52、积月累下来,类变得越来越大,越来越复杂。这种情况下,我们应该将其中的一部分提取出来创建一个新类。步骤:1.决定怎样来划分类的责任(哪些是原有类的责任,哪些是新类的责任)。2.创建一个新类。如果原有类的名称不再合适,也可以重新命名她。3.在原有类中创建一个对新类的引用。4.使用移动字段重构将要移动的字段移动到新的类中。5.编译并测试。6.使用移动方法重构将要移动的方法从原有类中移动到新的类中。7.编译并测试。8.检查两个类的接口和方法。9.决定是否要暴露新的类。如果要暴露,是否要采用不变对象的方法暴露。例子:原有的代码:class Person: 1. .2. private String _name;3. private String _officeAreaCode;4. private String _officeNumber;5.6. public String getName()7. return _name;8. 9.10. public String getTelephoneNumber()11. return (“(”+ _officeAreaCode + “)” + _officeNumber);12. 13.14. String getOfficeAreaCode()15. return _officeAreaCode;16. 17.18. void setOff

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!