ivaneeo's blog

自由的力量,自由的生活。

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks
范例(Examples)
在Replace Data Value with Object(175)一节中,我留下了一个重构后的程序,本节范例就从它开始。我们有下列的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 customer) {
       _customer = new Customer(customer);
    }

    public String getCustomer() {
       return _customer.getName();
    }
   
    public void setCustomer(String arg) {
       _customer = new Customer(arg);
    }
    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.getCustomer().equals(customer)) result ++;
    }
    return result;
}
到目前为止,Customer对象还是value object。就算多份定单属于同一客户,但每个order对象还是拥有各自的Customer对象。我希望改变这一现状,使得一旦同一客户拥有多份不同定单,代表这些定单的所有Order对象就可以共享同一个Customer对象。

首先我使用Replace Constructor with Factory Method(304)。这样,我就可以控制Customer对象的创建过程,这在以后会是非常重要的。我在Customer class中定义这个factory method
class Customer {
    public static Customer create(String name) {
       return new Customer(name);
    }
}
然后我把[对构造函数的调用]替换成[对factory method的调用]:
class Order {
    public Order(String 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 _instance = new Hashtable();

然后我得决定:应该在接到请求时创建新的Customer对象,还是应该预先将它们创建好。这里我选择后者。在应用程序的启动代码(start-up code)中,我先把需要使用的Customer对象加载妥当。这些对象可能来自数据库,也可能来自文件。为求简单起见,我在代码中明确生成这些对象。反正以后我总是可以使用Substitute Algorithm(139)来改变它们的创建方式。
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() {
       _instance.put(this.getName(), this);
    }
现在,我要修改factory method,让它返回预先创建好的Customer对象:
public static Customer create(String name) {
    return (Customer)_instance.get(name);
}
由于create()总是返回既有的Customer对象,所以我应该使用Rename Method(273)修改这个factory method的名称,以便强调(说明)这一点。
class Customer...
public static Customer getNamed(String name) {
    return (Customer)_instances.get(name);
}
posted on 2005-09-01 14:16 ivaneeo 阅读(180) 评论(0)  编辑  收藏 所属分类: refactoring-从地狱中重生

只有注册用户登录后才能发表评论。


网站导航: