有一个数据项,须要与其余数据和行为一块儿使用才有意义。将数据项变成对象。 java
开发初期,咱们以简单的数据项表示简单的状况。可是随着开发的进行,你可能会发现,这些简单数据项再也不那么简单了。好比说,一开始你可能会用一个字符串来表示“电话号码”概念,可是随后就会发现,电话号码须要“格式化”、“抽取区号”之类的特殊行为。若是这样的数据有一两个,还能够把相关函数放进数据项所属的对象里;可是Duplicate Code坏味道和Feature Envy坏味道很快就会从代码中散发出来。当这些坏味道开始出现,就应该将数据值变成对象。 函数
1.为带替换数据新建一个类,在其中声明一个final字段,其类型和源类中的带替换数值类型同样。而后在新类中加入这个字段的取值函数,再加上一个接受此字段为参数的构造函数。 测试
2.编译 this
3. 将源类中的带替换数值字段的类型改成前面新建的类。 spa
4. 修改源类中该字段的取值函数,令它调用新类的取值函数。 code
5. 若是源类构造函数中用到这个待替换字段,咱们就修改构造函数,令它改用新类的构造函数来对字段进行赋值动做。 对象
6.修改源类中待替换字段的设值函数,令它为新类建立一个实例。 开发
7.编译,测试 字符串
8. 如今,可能须要对新类使用Change Value to Reference. get
下面有一个表明“订单”的Order类,其中以一个字符串记录订单客户。如今,咱们但愿改用一个对象来表示客户信息,这样就有充裕的弹性保存客户地址、信用等级等信息,也得以安置这些信息的操做行为。Order类最初以下:
public class Order { private String customer; public Order( String customer ) { this.customer = customer; } public String getCustomer() { return customer; } public void setCustomer( String arg ) { customer = arg; } }
使用Order类的代码可能像下面这样:
private static int numberOfOrdersFor( Collection orders, String customer ) { int result = 0; Iterator<Order> iter = orders.iterator(); while( iter.hasNext() ) { Order each = iter.next(); if( each.getCustomer().equals( customer ) ) { result++; } } return result; }
首先,新建一个Customer类表示“客户”概念。而后在这个类中创建一个final字段,用以保存一个字符串,这是Order类目前所使用的。将这个新字段命名为name,为这个字符串加上取值函数和构造函数.
public class Customer { private final String name; public Customer( String name ) { this.name = name; } public String getName() { return name; } }如今,将Order中的customer字段的类型修改成Customer,并修改全部引用该字段的函数,让它们恰当地改而引用Customer对象。其中取值函数和构造函数的修改都很简单。至于设值函数,让它建立一个customer实例。
public class Order { private Customer customer; public Order( String customer ) { this.customer = new Customer( customer ); } public String getCustomer() { return customer.getName(); } public void setCustomer( String arg ) { customer = new Customer( arg ); } }设值函数须要建立一个Customer实例,这是由于之前的字符串是个值对象,因此如今的Customer对象也应该是个值对象。这也就意味着每一个对象都包含本身的一个Customer对象。注意这样一条规则:值对象应该是不可修改内容的--这即可避免一些讨厌的别名问题。
咱们须要观察Order类中的customer字段的操做函数,并做出一些修改,使它更好地反映出修改后的新形势。对于取值函数,可使用Rename Method改变名称,让它更清晰地表示,它所返回的是消费者名称,而不是个Customer对象。
public void setCustomerName( String arg ) { customer = new Customer( arg ); }至于构造函数和设值函数,就没必要修改其签名了,但参数名称得改:
public Order( String customerName ) { customer = new Customer( customerName ); } public void setCustomerName( String customerName ) { customer = new Customer( customerName ); }后继的其余重构也许会添加“接受现有Customer对象做为参数”的构造函数和设值函数。