Move Field (搬移字段)

Summary:  

程序中,某个字段被其所驻类以外的另外一个类更多地用到。在目标类新建一个字段,修改源字段的全部用户,令它们改用新字段。 java

Motivation: 

 在类之间移动状态和行为,是重构过程当中必不可少的措施。随着系统的发展,你会发现本身须要新的类,并须要将现有工做责任拖到新类中。 函数

对于一个字段,在其所驻类以外的另外一个类中有更多函数使用了它,咱们就能够考虑搬移这个字段。上述所谓“使用”多是经过设值/取值函数间接进行的。咱们也可能移动该字段的用户(某个函数),这取决因而否须要保持接口不受变化。若是函数看上去更适合待在原地,那么就搬移字段。 测试

Mechanics: 

1. 若是字段的访问级是public,使用 Encapsulate Field将它封装起来。 this

若是有可能移动移动那些频繁访问该字段的函数,或若是有许多函数访问某个字段,先使用SelfEncapsulate Field也许会有帮助。 spa

2.编译,测试 rest

3.在目标类中创建与源字段相同的字段,并同时创建相应的设值/取值函数。 code

4. 编译目标类。 对象

5. 决定如何在源对象中引用目标对象。 接口

可能会有一个现成的字段或函数帮助取得目标对象。若是没有,就看可否轻松创建一个这样的函数。若是仍是不行,就得在源类中新建一个字段来保存目标对象。这多是一个永久性修改,但也可让它是暂时的,由于后继的其余重构项目可能会把这个新建字段去掉。 get

6. 删除源字段。

7.将全部对元字段的引用替换为对某个目标函数的调用。

若是须要读取该变量,就把对源字段的引用替换为对目标取值函数的调用;若是要对该变量赋值,就把对源字段的引用替换成对设值函数的调用。

若是源字段不是private的,就必须在源类的全部子类中查找源字段的引用点,并进行相应替换。

           8. 编译,测试。

范例1

下面是Account类的部分代码


public class Account
{
    private AccountType type;

    private double interestRate;

    double interestForAmountDays( double amount, int days )
    {
        return interestRate * amount * days / 365;
    }
}
咱们把表示利率的interestRate搬移到AccountType类去。目前已有数个函数引用了它,interestForAmountDays() 就是其一。下一步咱们要在AccountType中创建interestRate字段以及相应的访问函数:



public class AccountType
{
    private double interestRate;

    public double getInterestRate()
    {
        return interestRate;
    }

    public void setInterestRate( double interestRate )
    {
        this.interestRate = interestRate;
    }
}
这时候,能够编译新的AccountType类了。


如今咱们须要让Account类中访问interestRate字段的函数转而是用AccountType对象,而后删除Account类中的interestRate字段。咱们必须删除源字段,才能保证其访问函数的确改变了操做对象,编译器会帮咱们指出未被正确修改的函数。


public class Account
{
    private AccountType type;

    double interestForAmountDays( double amount, int days )
    {
        return type.getInterestRate() * amount * days / 365;
    }
}

范例2:使用Sel-Encapsulation

若是有不少函数已经使用了interestRate字段,我应该先运用Self-Encapsulate Field(自我封装)


public class Account
{
    private AccountType type;

    private double interestRate;

    double interestForAmountDays( double amount, int days )
    {
        return getInterestRate() * amount * days / 365;
    }

    private void setInterestRate( double arg )
    {
        interestRate = arg;
    }

    private double getInterestRate()
    {
        return interestRate;
    }
}
这样,在字段搬移以后,我就只须要修改访问函数;



public class Account
{
    private AccountType type;

    double interestForAmountDays( double amount, int days )
    {
        return getInterestRate() * amount * days / 365;
    }

    private void setInterestRate( double arg )
    {
        type.setInterestRate( arg );
    }

    private double getInterestRate()
    {
        return type.getInterestRate();
    }
}


之后如有必要,咱们能够修改访问函数的用户,让它们使用新对象。Self-Encapsulate Field是的咱们得以保持小步前进。若是我须要对类作许多处理,保持小步前进时有帮助的。特别值得一提的是:首先使用Self-Encapsulate Field是咱们得以更轻松使用Move Method将函数搬移到目标类中。若是待搬移函数引用了字段的访问函数,那些引用点是无需修改的。

相关文章
相关标签/搜索