《重构》- Change Reference to Value 的一点疑问

rangeon 2009-09-02 10:28:06
正在看《重构》,在212页有个实例代码有点不解,请教各位大牛,下面是内容摘录:

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


上面这句代码Currency的构造函数是private,怎么还能new呢?不应该是return false啊,应该是编译时就出错才对啊。
...全文
117 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
b63772428 2009-09-16
  • 打赏
  • 举报
回复
《重构》这本书的的购买链接有没有?
rangeon 2009-09-03
  • 打赏
  • 举报
回复
谢谢高人指点!
我想也是,这样的确有点误导人,
new Currency("USD").equals(new Currency("USD")) // returns false
该改为
new Currency("USD").equals(new Currency("USD")) // compile error
才对。
imasmallbird 2009-09-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 rangeon 的回复:]
另外问一下,Duplicate Observed Data方法不太理解,看了例子,感觉这个方法的目的是把UI相关的数据独立到一个对象中,既然是这样,为什么还要在UI类内部创建这个对象呢?感觉应该在UI类外部创建这个对象,传入到UI类中才对啊,而且例子中的过程那么复杂有必要吗?不就是要同步数据吗?在UI类设置数据的函数中添加一句设置外部对象数据的代码不就行了吗?为什么要搞这么复杂呢?
[/Quote]

这个之前也看过了一遍,但是感觉暂时用不上,而且确实较难理解,就没有继续看下去~
等人来解释,跟着学习~

不过这本书确实挺好,至少对我的影响非常非常大,有空再重看一遍~~
imasmallbird 2009-09-02
  • 打赏
  • 举报
回复
楼上有点手误,打错了个地方
还应该是不能够创建实例(原为函数,改正一下)
imasmallbird 2009-09-02
  • 打赏
  • 举报
回复
他这段话应该是这样理解的
Currency class维护一个实体链表(list of instances);我不能直接使用构造函数创建实体,因为Currency构造函数是private。
new Currency("USD").equals(new Currency("USD")); //return false

这要连在一起看,他后面的return false,应该不仅仅是说值不相等,而且还应该是不能够创建函数
因为后文中
可以把构造函数声明为public,直接以构造函数获取Currency实体,从而去掉Currency class中的factory method和[控制实体创建]的行为:
new Currency("USD").equals(new Currency("USD")); //now returns true

这段话指明了,去掉了[控制实体创建]的行为,也就是可以new了,这里的//now returns true也应该不仅仅是值相等,也应该是可以new了。
但是感觉还是有点牵强,有没有英文原版的?
感觉看这书理解主要重构手段就行,这种语法上的别管了~,只要是构造函数为private那么外面的类就肯定不能直接new了
rangeon 2009-09-02
  • 打赏
  • 举报
回复
另外问一下,Duplicate Observed Data方法不太理解,看了例子,感觉这个方法的目的是把UI相关的数据独立到一个对象中,既然是这样,为什么还要在UI类内部创建这个对象呢?感觉应该在UI类外部创建这个对象,传入到UI类中才对啊,而且例子中的过程那么复杂有必要吗?不就是要同步数据吗?在UI类设置数据的函数中添加一句设置外部对象数据的代码不就行了吗?为什么要搞这么复杂呢?
rangeon 2009-09-02
  • 打赏
  • 举报
回复
多谢老大关注,下面是例子的全部内容:

范例(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
knightzhuwei 2009-09-02
  • 打赏
  • 举报
回复
能不能再多摘录一些 我觉得new Currency("USD").equals(new Currency("USD")); //return false 这句话怎么跟前面没啥关系呢。。。

50,499

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧