我不认为你应该考虑任何这些属性作为实际的成员变量。你应该有一个“属性”对象,它包含一个属性(这将类似于一个成员变量)和一个具有属性集合的“集合”对象(它将像一个类)。
由于这些属性和集合真的没有与它们相关的代码,这将毫无意义,以实现它们的对象(将在屁股真正的痛苦)
你的属性和集合需要保存所有特定于他们的数据。例如,如果一个字段最终写入数据库,它需要将表名存储在某个地方。如果需要写入屏幕,那也需要存储在某个地方。
范围/值检查可以“添加”到属性,因此当您定义属性的数据类型时,可能会有一些文本显示“MaxLength(12)”,它将实例化一个名为MaxLength的类值12,并将该类存储到属性中。只要属性的值发生变化,新的值就会被传递给已经应用到这个类的每个范围检查器。可以有多种与该课程相关的动作。
这只是基础。我已经设计出这样的东西,这是一个很好的工作,但它比试图用一种直白的语言简单得多。
我知道这看起来像是太多的工作了(它应该如果你真的得到我建议的),但记住它,最终你可能会去“哼,也许这是值得的尝试毕竟“。
编辑(回应评论):
我想过尝试与注册表/关键的事情(我们还在讨论属性值对)工作,但它不太适合。
您试图将DAO放入Java对象中。这真的很自然,但我认为这只是解决DAO/DTO问题的一种不好的方法。 Java对象具有对这些属性起作用的属性和行为。对于你正在做的事情,没有任何行为(例如,如果用户创建一个“生日”字段,你将不会使用目标代码来计算他的年龄,因为你不知道生日是什么)。
所以,如果你抛弃了对象和属性,你将如何存储这些数据?
让我走一个非常简单的第一步(非常接近您提到的注册表/标记系统):在哪里使用对象,使用散列表。对于属性名称,使用键,对于属性值,使用散列表中的值。
现在,我将介绍我用来增强这个简单模型的问题和解决方案。
问题: 你已经失去了强类型,你的数据是非常自由的格式(这可能是坏的)
解决方案: 作出“属性”基类中的场所使用散列表中的值。扩展IntegerAttribute,StringAttribute,DateAttribute,...的基类不要允许不适合该类型的值。现在你已经拥有了强大的输入,但它是运行时而不是编译时 - 可能没问题,因为你的数据在运行时实际上是DEFINED的。
问题: 格式化程序和验证程序
解决方案: 必须创建一个插件为您的属性基类的能力。您应该可以为任何属性设置“setValidator”或“setFormatter”。验证器/格式化程序应该使用该属性 - 因此,当您保存属性时,您可能必须能够将它们序列化到数据库。
这里很好的一点是,当你在属性上执行“attribute.getFormattedValue()”时,它已经预先格式化显示。如果任何验证失败,attribute.setValue()将自动调用验证器并抛出异常或返回错误代码。
问题: 如何在屏幕上显示这些信息?我们已经有了getFormatted(),但它在屏幕上显示的是什么?我们用什么标签?什么样的控件应该编辑这个字段?
解决方案: 我会将所有这些东西存储在每个属性中。 (顺序应该存储在类中,但是因为这是一个哈希表,所以它不会工作 - 那么我们会在下一步)。如果您存储显示名称,用于呈现此内容的控件类型(文本字段,表格,日期...)和数据库字段名称,则此属性应具有它需要与显示和数据库I/O例程编写来处理属性。
问题: 该Hashtable是一个糟糕的DAO接口。
解决方案: 这是绝对正确的。你的散列表应该被包装在一个知道它所拥有的属性集合的类中。它应该能够将自身(包括其所有属性)存储到数据库 - 可能需要辅助类。它应该可以通过一个方法调用来验证所有的属性。
问题: 如何实际使用这些东西?
解决方案: 由于它们包含自己的数据,因此它们在系统中任何与它们交互的地方(比如屏幕或数据库)都需要一个“适配器”。
假设您正在展示一个屏幕来编辑您的数据。您的适配器将传递一个框架和一个基于散列表的DTO。
首先它会按顺序遍历属性列表。它会问第一个属性(比如一个字符串)它想要用来进行编辑的控件类型(比如文本字段)。
它会创建一个文本字段,然后它会将一个侦听器添加到将更新数据的文本字段,这会将您的数据绑定到屏幕上的控件。
现在只要用户更新控件,更新就会发送到属性。该属性存储新值,你就完成了。
(这将通过一个“OK”按钮,所有的值在一次迁移的概念很复杂,但我仍然会设专人之前每个绑定,然后使用“OK”作为触发。)
这种绑定可能很困难。我用手工完成了这个工作,一旦我使用了一个名为“JGoodies”的工具包,这个工具包内置了一些绑定功能,这样我就不必亲自编写每个可能的绑定组合,但是我不确定从长远来看它节省了很多时间。
这太长了。我将在某一天创建一个DAO/DTO工具包 - 我认为Java对象完全不适合作为DAO/DTO对象。
如果您仍然难住,请随时Email/IM me - billmail在gmail ..
我不想与任何特定系统紧密联系,但我已经在考虑使用Apache Jackrabbit作为后备存储。我大多需要一个很好的DAO模型来表达一个好的通用接口。 – BobMcGee 2009-04-23 20:01:05
我对Jackrabbit并不熟悉,但看起来它实现了Java内容库规范。该规范应该为您提供通用节点,属性等API。至于DAO,看起来Spring对JCR有很好的支持,并且使用它们的框架实现了DAO: https://springmodules.dev.java。 net/docs/reference/0.6/html/jcr.html – Andrew 2009-04-23 20:11:42