关于封装的问题(书:HF OOA& D)

时间:2011-02-17 22:43:10

标签: java oop ooad

我正在读这本书(Head First Object Oriented Design& Analysis)。在第5章中有一个建议,我想对此有一些其他的强硬态度。这本书说:

  

“当你有一组属性时   不同的对象,使用a   集合,就像存储那些的Map   动态地说。“

以及更多,解释为什么这样做:

  

“你将删除许多方法   你的课程,并避免不得不   在新属性时更改代码   已添加到您的应用“。

我确实理解这种方法的优点,但也不是缩小尺寸吗?我的意思是如果我使用地图来存储这些信息(在示例中它是一个String to Enum map)并提供一个getProperty(String)方法来访问,这个方法的调用者实际上必须知道允许哪些字符串。我不喜欢这个。我的意思是你当然可以争辩说可以在javadoc中说明哪个输入是允许的。

这真的是解决这类问题的方法还有其他选择吗?我知道用继承做这个是不好的,因为大量的子类和那些子类不会覆盖任何东西只是添加新的属性,这在我的意见中并不是那么好。

3 个答案:

答案 0 :(得分:5)

我个人认为使用Map代替实际字段是个糟糕的主意。我不幸地使用了广泛使用这种(反)模式的系统,这是一个维持的噩梦。

我认为没有理由使用地图进行“未来验证”,你可以避免添加新方法的论点是可笑的,特别是当你考虑添加一个新字段需要大约20次击键时,添加getter和setter for再点击3-4次鼠标。你获得的是什么,你失去的是类型安全和编译时间检查,控制和监视正在设置的内容以及何时的能力,更不用说你打破了封装原则这一事实。

还应该注意的是,Java语言本身的开发已经朝着越来越多的编译时检查,枚举和泛型是这个方向最明显的例子。扔掉它比在1.3-1.4时代更糟糕

映射只应在某些内容真正动态时使用,即在编译时无法识别密钥列表。

答案 1 :(得分:2)

您可以实施getProperty方法接受enum值作为密钥。这将提供一种向用户显示哪些密钥有效的简单方法,并且当您想要添加更多密钥时甚至不必修改原始enum,因为您可以扩展enum。当然,修改原始enum可能更容易,因为拥有enum继承层次结构会让人感到困惑。

答案 2 :(得分:1)

是的,您必须知道检索数据的密钥。不,这不会导致任何根本性的改变;如果您使用了类层次结构,则需要知道要调用的类和方法的名称。

请注意,您可以在不事先知道名称的情况下对地图中的项目进行某些使用 - 您可以遍历地图并(例如)向用户显示值,允许修改,让他们将特定键应用于特定设置。

我不是说这不一定是个好主意,但无论这是否是个好主意都可以做到。