Steve Yegge在他的blog post中描述了属性模式。
对于使用C#或Java等静态语言的人来说,这种方法有哪些优点和缺点?在什么样的项目中你想要使用属性模式,什么时候你想避免它?
答案 0 :(得分:5)
我最近一直在深入研究这种模式,我可以告诉你,找到它的信息非常困难。 Yegge将其称为原型或属性,但这两者都被严重过度使用,并且众所周知为另外两种不同的模式。有些人将Yegge提出的系统称为“字符串[sic]类型”,这是另一种研究途径。
这是一个非常巧妙的想法,在某些应用程序中有很多优点,在其他应用程序中有很多错误。你获得的本质上是一种在运行时构建“类型”的非常灵活的方法,但你会失去许多强类型检查语言。实现它的最简单方法是Dictionary<string,string>
。然后你必须使用强制转换来将你的字符串值作为实际值返回。保持这种设计可管理性的关键是如果可以避免,就永远不要直接引用代码中的属性。如果该插槽的“规范”名称发生变化,theProtoObject["owner"] = "protoman"
之类的内容将会扼杀您。它也可能导致像JavaScript这样的问题(在它下面使用这种模式作为对象模型),如果你拼错了键名,你将添加一个新的插槽。
您可能在生产系统中进行的一次非常可能的升级是使用某种特殊类型的值,以及键的某种“重键”,这样您就可以获得一些额外的打字和安全性关于你的模特的信息。
我见过一些使用它的应用程序。最近一个令人惊讶的例子让我在查看行业中的开源代码时发现了我:保险报价。 OpenQuote是一个非常灵活的项目,用于引用任何一般类型的保险。它是用Java编写的,但是如果你知道C#就应该读得很好。它的核心是Type
对象,它包含以下代码:
/** A dynamic collection of attributes describing type */
private List<Attribute> attribute = new ArrayList<Attribute>();
什么是Attribute
?这样:
* 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概述的内容。性能可能很糟糕,尤其是在实施过程中。类型检查和安全性受到打击,您的对象更难以推理,因为您不确定它们上面有哪些属性。
答案 1 :(得分:3)
属性模式特别有用(或者,对我而言),当你想要制作对象的原型或者有一个开发结构,这有点迫使你有一个API /接口的迭代部署。
如果你开始考虑一个对象的某些属性,那么你就可以创建它们。稍后您会发现(并且您已经预料到这一发现......)您对主题区域的理解不充分,您可以根据第一个对象的原型制作新的对象设计/行为。等等。关于这个主题的wiki页面与静态类型语言一起非常好地描述了这个主题,但如果你真的认真对待原型开发,我建议你研究一下JavaScript或Lua。原型的属性在静态类型语言中是不可变的,这一事实最终会让你不知所措。
编辑:哦,我看到你链接到关于这个主题的优秀帖子。 Yegges使用/解释主题当然会使我自己相形见绌。请阅读几次,并且您应该非常清楚使用java等语言中的属性模式的优点/含义。
Edit.2:链接到维基百科文章:http://en.wikipedia.org/wiki/Prototype_pattern
答案 2 :(得分:0)
对于使用Java的人,在我阅读本文时,我会说你不能在任何项目上使用属性模式,因为引用:
Java基本上不支持属性模式。
出于同样的原因,C#也是如此。当我谈到这个陈述时,我感到有点安慰,因为我肯定没有找到任何方法让他们在一起。
所以我不确定我理解你的问题。但是感谢这个链接 - 仅仅为此提出了问题。现在我理解了一些事情,我中途变得更好了。