依恋情结----MoveMethod谷歌德语在线翻译
⽏容置疑,搬移⽅法(Move Method)应该是最常⽤的重构⼿段之⼀,正因为太常⽤⽽且较为简单,以⾄于很多⼈并不认为它是⼀种很有价值的重构,但事实并⾮如此,在最初的代码诞⽣之后,有些⽅法可能会被放在⼀些不合适的地⽅,例如,⼀个⽅法被其他类使⽤⽐在它所在的类中的使⽤还要频繁或者⼀个⽅法本⾝就不应该放在某个类中时,我们应该考虑将它移到更合适的地⽅。搬移⽅法,顾名思义就是将⽅法搬移⾄合适的位置,如将⽅法搬移到更频繁地使⽤它的类中。与搬移⽅法相似的还有⼀种重构⼿段是搬移字段(Move Field),即搬移属性。
在《重构:改善既有代码的设计》⼀书中,多种坏味都需要使⽤搬移⽅法来进⾏重构,例如依恋情结(Feature Envy)、霰弹式修改(Shotgun Surgery)、平⾏继承结构(Parallel Inheritance Hierarchies)、异曲同⼯的类(Alternative Class with DifferentInterfaces)、狎昵关系(Inappropriate Intimacy)、纯稚的数据类(Data Class)等,通过搬移⽅法(Move Method)或者搬移字段(Move Field),可以让某些代码待在更合适的位置。因此,Martin Fowler在《重构》⼀书中指出,“搬移⽅法”是重构理论的⽀柱(Moving methods is the bread and butter of refactoring.),可见该重构的重要性。
下⾯举⼀个例⼦来加以说明:
【重构实例】
在某银⾏系统中包含⼀个银⾏账户类BankAccount和账户利息类AccountInterest,重构之前的代码如下:
[java]
1. factoring.two.before;
2.
3. class BankAccount {
4. private int accountAge;
5. private int creditScore;
6. private AccountInterest accountInterest;
7.
8. public BankAccount(int accountAge, int creditScore, AccountInterest accountInterest) {
9. this.accountAge = accountAge;
10. ditScore = creditScore;
11. this.accountInterest = accountInterest;
12. }
13.
14. public int getAccountAge() {
15. return this.accountAge;
16. }
17.
18. public int getCreditScore() {
19. ditScore;
20. }
21.
22. public AccountInterest getAccountInterest() {
23. return this.accountInterest;
24. }
25.
26. public double calculateInterestRate() {
27. if (ditScore > 800) {
28. return 0.02;
29. }
30.
31. if (this.accountAge > 10) {
32. return 0.03;
33. }
34.
35. return 0.05;
36. }
37. }
38.
39. class AccountInterest {
40. private BankAccount account;
41.
42. public AccountInterest(BankAccount account) {
43. this.account = account;
44. }
45.
46. public BankAccount getAccount() {
47. return this.account;
48. }
49.
50. public double getInterestRate() {
51. return account.calculateInterestRate();
52. }
53.
54. public boolean isIntroductoryRate() {
55. return (account.calculateInterestRate() < 0.05);
56. }
57. }
在上述代码中,很明显,AccountInterest使⽤calculateInterestRate()⽅法更为频繁,它更希望得到该⽅法,因此,我们需要成⼈之美,,将calculateInterestRate()⽅法从BankAccount类搬移到AccountInterest类中。
重构之后的代码如下:
[java]
1. factoring.two.after;
晒黑后怎样快速美白2.
3. class BankAccount {
4. private int accountAge;
5. private int creditScore;
6. private AccountInterest accountInterest;
7.
8. public BankAccount(int accountAge, int creditScore, AccountInterest accountInterest) {
9. this.accountAge = accountAge;
10. ditScore = creditScore;
11. this.accountInterest = accountInterest;
12. }
13.
14. public int getAccountAge() {
15. return this.accountAge;
16. }
17.
18. public int getCreditScore() {
19. ditScore;
20. }
21.
22. public AccountInterest getAccountInterest() {contrary
23. return this.accountInterest;
24. }
25. }
26.
27. class AccountInterest {
28. private BankAccount account;
29.
30. public AccountInterest(BankAccount account) {
31. this.account = account;
32. }
33.
34. public BankAccount getAccount() {
35. return this.account;
36. }
37.
38. public double getInterestRate() {
39. return calculateInterestRate();
40. }
41.
42. public boolean isIntroductoryRate() {
43. return (calculateInterestRate() < 0.05);
44. }
mhs45.
46. //将calculateInterestRate()⽅法从BankAccount类搬移到AccountInterest类
47. public double calculateInterestRate() {
48. if (CreditScore() > 800) {
49. return 0.02;
50. }
51.
52. if (AccountAge() > 10) {
skinny love53. return 0.03;
伴鱼少儿英语54. }
55.
56. return 0.05;
57. }
58. }sor
通过重构,BankAccount类更加符合单⼀职责原则,它负责存储银⾏账户信息,⽽对账户的操作(例如计算利息等)⽅法则转移到其他经常使⽤且适合它的类中,这样让代码变得更加合理,也有助降低类之间的耦合度,增强代码的可扩展性和可维护性。
重构⼼得:
我慢
搬移⽅法是⼀种⾮常实⽤的重构⼿段。在本实例中,我们是将⽅法搬移到被调⽤次数最多的那个类中,在实际代码重构过程中,还有很多其他涉及到需要搬移⽅法的场景。
有⼀种代码味道叫做依恋情结(Feature Envy),指的是⼀个⽅法对某个类的兴趣⾼过对⾃⼰所处类的兴趣,例如某个⽅法需要访问另⼀个类中⼤量的数据成员,此时,也⾮常适合使⽤搬移⽅法重构。让⽅法能够前往它的梦想王国不是件很有意义的事情吗?如果⼀个⽅法⽤到了多个类的功能,那么这个⽅法放在哪个类中更合适呢?常⽤的做法是判断哪个类拥有最多被此⽅法使⽤的数据,然后将这个⽅法和那些数据放在⼀起。在这种情况下,搬移⽅法的时机不是判断它被哪个类调⽤更多,⽽是判断它更需要哪个类提供的数据,这跟上⾯的重构实例有些区别。
有时候搬移⽅法时,还需要将只被这个(或这些)⽅法使⽤的数据和其他⽅法⼀起搬移,需要认真检查⽅法中使⽤到的属性(字段)和其他⽅法,必要时同时执⾏搬移字段重构(Move Field)。
英语单词mp3下载
kair kuo
如果搬移后的⽅法需要访问原有类中的属性或者⽅法,可以将原有类的对象作为参数传⼊新类,在这个过程中可能还需要修改原有类中某些属性或⽅法的可见性,毕竟它们已经分家了,原有的⼀些私有的东西是不能再直接访问的。
如果在继承结构中,需要搬移的⽅法声明在抽象层中,此时要慎重使⽤本重构,如果太⿇烦建议就不要搬移了,免得引⼊太多错误,毕竟我们要保证抽象层的相对稳定性。
如果有需要,可以为搬移后的函数重新取⼀个名字,以提⾼代码的可读性。
如果原有类还需要⽤到这个已经搬移⾛的⽅法,可以通过在原有类中提供⼀个委托⽅法的形式来实现,例如method() { TargetClass tc = new TargetClass (); tc.method();},如果原有类中的多个⽅法(当然也不能太多,否则就没有必要搬⾛了)需要使⽤已搬移⾛的⽅法,也可以考虑在原有类中增加⼀个⽬标类(搬移之后所在类)的对象引⽤,通过该引⽤来调⽤搬⾛的⽅法。
当⼀个类的职责太多时,为了分解类的职责,也可能需要将⼀些职责搬移到其他类中,此时也需要执⾏搬移⽅法重构。这样做,系统将更加满⾜单⼀职责原则,有利于提⾼代码的可复⽤性和易理解性。
虽然搬移⽅法是⼀种简单的重构⼿段,但是在实际使⽤中很多⼈经常会遇到⼀个问题,如何确定和寻找重构时机?也就是不知道什么时候该⽤搬移⽅法来进⾏重构,特别是当系统较为复杂,类和⽅法个数⾮常多时,要准确识别出重构时机并不是⼀件简单的事情。