潍坊做网站建设的公司,南京网站推广价格,南沙企业网站建设,广州百度关键词排名重构数据-Change Value to Reference将实值对象改为引用对象三
1.将实值对象改为引用对象
1.1.实值对象和引用对象区别
下面通过客户Customer和订单Order两个对象介绍下它们的区别 值对象#xff1a;当一个客户Customer下了多个订单Order后#xff0c;每个订单类都将创建一…重构数据-Change Value to Reference将实值对象改为引用对象三
1.将实值对象改为引用对象
1.1.实值对象和引用对象区别
下面通过客户Customer和订单Order两个对象介绍下它们的区别 值对象当一个客户Customer下了多个订单Order后每个订单类都将创建一个客户对象即使多个订单属于同一个客户但每个Order对象还是拥有各自的Customer对象。所以对于多个订单Order来说没办法共享同一个客户的信息。
引用对象同 一客户拥有多份不同定单代表这些定单的所有Order对象就可以共享同一个Customer对象以及对象中的所有属性信息。
1.2.使用场景
当A和B两个对象之间是1对多关系时就可以将值对象转为引用对象。实现的方法有很多中例如单例模式就是其中的一种。 例如上面的客户和订单关系就是1对多关系多个订单共享同一个客户对象。
1.3.如何做
使用Replace Constructor with Factory Method (304)。编译测试。决定由什么对象负责提供访问新对象的途径。可能是一个静态字典或一个注册表对象。你也可以使用多个对象作为新对象的访问点。决定这些引用对象应该预先创建好或是应该动态创建。如果这些引用对象是预先创建好的而你必须从内存中将它们读取出来那么就得确保它们在被需要的时候能够被及时加载。修改工厂函数令它返回引用对象。如果对象是预先创建好的你就需要考虑万一有人索求一个其实并不存在的对象要如何处理错误你可能希望对工厂函数使用Rename Method (273)使其传达这样的信息它返回的是一个既存对象。编译测试。
1.4.示例
在Replace Data Value with Object 一节中我留下了一个重构后的程序本节范例就从它开始。我们有下列的Customer class class Customer {public Customer (String name) {_name name;}public String getName() {return _name;}private final String _name;}它被 Order class使用 class Order...public Order (String customerName) {_customer new Customer(customerName);}public void setCustomer(String customerName) {_customer new Customer(customerName);}public String getCustomerName() {return _customer.getName();}private Customer _customer;此外还有一些代码也会使用Customer对象 private static int numberOfOrdersFor(Collection orders, String customer) {int result 0;Iterator iter orders.iterator();while (iter.hasNext()) {Order each (Order) iter.next();if (each.getCustomerName().equals(customer)) result;}return result;}到目前为止Customer对象还是value object。就算多份定单属于同一客户但每个Order对象还是拥有各自的Customer对象。 我希望改变这一现状使得同 一客户拥有多份不同定单代表这些定单的所有Order对象就可以共享同一个Customer对象。本例中这就意味每一个客户名称只该对应一个Customer对象。
首先我使用 Replace Constructor with Factory Method。这样我就可以控制Customer对象的创建过程这在以后会是非常重要的。我在Customer class中定义这个factory method
class Customer {
// 创建一个实例化Customer对象方法该方法称为工厂方法public static Customer create (String name) {return new Customer(name);}然后我把「对构造函数的调用」替换成「对factory method的调用」 class Order {public Order (String customer) {// 调用工厂方法创建Customer对象_customer Customer.create(customer);}然后我再把构造函数声明为private class Customer {private Customer (String name) {_name name;}现在我必须决定如何访问Customer对象。 我比较喜欢通过另一个对象例如Order class中的一个值域来访问它。但是本例并没有这样一个明显的值域可用于访问Customer对象。 在这种情况下我通常会创建一个注册登录对象作为访问点。为了简化我们的例子我把Customer对象保存在Customer class的一个static值域中让Customer class作为访问点
private static Dictionary _instances new Hashtable();然后我得决定应该在接到请求时创建新的Customer对象还是应该预先将它们创建好。这里我选择后者。 在应用程序的启动代码start-up code中我先把需要使用的Customer对象加载妥当。这些对象可能来自数据库也可能来自文件。为求简单起见我在代码中明确生成这些对象。反正以后我总是可以使用 Substitute Algorithm 来改变它们的创建方式。 class Customer...static void loadCustomers() {new Customer (Lemon Car Hire).store();new Customer (Associated Coffee Machines).store();new Customer (Bilston Gasworks).store();}private void store() {_instances.put(this.getName(), this);}现在我要修改factory method让它返回预先创建好的Customer对象 public static Customer create (String name) {return (Customer) _instances.get(name);}由于create()总是返回既有的Customer对象所以我应该使用Rename Method 修改这个factory method的名称以便强调说明这一点。 class Customer...public static Customer getNamed (String name) {return (Customer) _instances.get(name);}