ivaneeo's blog

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

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks
范例(Examples)
让我们从一个表示[货币种类]的Currency class开始:
class Currency...
    private String _code;

    public String getCode() {
       return _code;
    }

    private Currency(String code) {
       _code = code;
    }
这个class所做的就是保存并返回一个货币种类代码。它是一个reference object,所以如果要得到它的一份实体,必须这么做:
    Currency usd = Currency.get("USD");
Currency class维护一个实体链表(list of instances);我不能直接使用构造函数创建实体,因为Currency构造函数是private。
new Currency("USD").equals(new Currency("USD"));   //return false

要把一个reference object变成value object,关键动作是:检查它是否为immutable(不可变)。如果不是,我就不能使用本项重构,因为mutable(可变的)value object会造成令人苦恼的别名现象(aliasing)。

在这里,Currency对象是不可变的,所以下一步就是为它定义equals():
public boolean equals(Object arg) {
    if(!(arg instanceof Currency)) return false;
    Currency other = (Currency)arg;
    return (_code.equals(other._code));
}

如果我定义equals(),我必须同时定义hashCode()。实现hashCode()有个简单办法:读取equals()使用的所有值域的hash codes,然后对它们进行bitwise xor(^)操作。本例中这很容易实现,因为equals()只使用了一个值域:
public int hashCode() {
    return _code.hashCode():
}
完成这两个函数后,我可以编译并测试。这两个函数的修改必须同时进行,否则依赖hashing的任何群集对象(collections,例如Hashtable、HashSet和HashMap)可能会产生意外行为。

现在,我想创建多少个等值的Currency对象就创建多少个。我还可以把构造函数声明为public,直接以构造函数获取Currency实体,从而去掉Currency class中的factory method和[控制实体创建]的行为:
new Currency("USD").equals(new Currency("USD"));   //now returns true
posted on 2005-09-05 11:04 ivaneeo 阅读(268) 评论(0)  编辑  收藏 所属分类: refactoring-从地狱中重生

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


网站导航: