我最近对这种模式进行了相当多的研究,我可以告诉你,找到有关它的信息非常困难。 Yegge 将其称为原型或属性,但这两种模式都被严重过度使用,并且众所周知的是另外两种不同的模式。有些人将像 Yegge 提出的系统称为“字符串[原文如此]类型”,所以这是另一种研究途径。
这是一个非常好的想法,在某些应用中具有很多优点,但在其他应用中却有很多缺点。您获得的本质上是一种在运行时构建“类型”的非常灵活的方法,但是您失去了许多语言的强类型检查来执行此操作。实现它的最简单方法是Dictionary<string,string>
。然后,您必须使用强制转换将字符串值恢复为实际值。保持此类设计易于管理的关键是,如果可以避免的话,永远不要在代码中直接引用属性。像这样的东西theProtoObject["owner"] = "protoman"
如果该插槽的“规范”名称发生变化,就会杀死你。它还可能导致 JavaScript 等问题(它使用下面的模式作为对象模型),如果您拼错了键名,就会添加一个新的槽。
您可能在生产系统中进行的一个很可能的升级是对值使用某种专用类型,对键使用某种“重键”,这样您就可以在您的系统上获得一些额外的打字和安全信息。模型。
我见过一些使用它的应用程序。最近,在查找我所在行业的开源代码时,我想到了一个令人惊讶的例子:保险报价。公开报价 http://openquote.appliedindustriallogic.com/是一个非常灵活的项目,适用于任何一般类型的保险报价。它是用 Java 编写的,但如果您了解 C#,它应该读起来很好。其核心在于Type
对象,其中包含这段代码:
/** A dynamic collection of attributes describing type */
private List<Attribute> attribute = new ArrayList<Attribute>();
什么是Attribute
? This:
* An attribute is defined as "One of numerous aspects, as of a subject". Generally, another
* type will own a (composite) collection of Attributes which help describe it.
所以基本上Attribute
是一种键值对,包含唯一的字符串 ID(字段名称)和字符串值,以及与一些正则表达式结合的类型枚举以验证和处理值。通过这种方式,它可以存储多种类型的值,并将它们转换回 java 值,同时提供一定的安全性。
然后,它继续在该核心之上构建许多特定于领域的模型类型。因此,保险单对象可以被视为具有灵活的、可扩展的福利列表,可以在运行时添加、删除或修改。每个好处的属性也可以扩展或减少。
这是正在使用的模式的一个例子,也是它的一个不错的用例:保险单可以非常灵活,在销售时可以由承保人随意决定,因此高度灵活的模型非常适合它。
但缺点几乎就是 Yegge 所概述的那样。性能可能很差,尤其是在简单的实现中。类型检查和安全性受到影响,并且您的对象更难以推理,因为您不确定它们的属性。