属性模式有哪些优缺点?

时间:2021-11-25 22:55:20

Steve Yegge describes the Properties Pattern in a blog post of his.

Steve Yegge在他的博客文章中描述了属性模式。

For someone using a static language like C# or Java, what are the advantages and disadvantages of this approach? In what kind of projects would you want to use the Properties Pattern, and when would you want to avoid it?

对于使用C#或Java等静态语言的人来说,这种方法有哪些优点和缺点?在什么样的项目中你想使用属性模式,什么时候你想避免它?

3 个解决方案

#1


I've been digging into this pattern quite a bit myself lately, and I can tell you that finding information on it is pretty tough. Yegge calls it prototype or properties, but both of those are pretty heavily overused, and well known as two other, different patterns. Some people refer to systems like the one Yegge proposes as "stringly[sic] typed" so that's another avenue of research.

我最近一直在深入研究这种模式,我可以告诉你,找到它的信息非常困难。 Yegge将其称为原型或属性,但这两者都被严重过度使用,并且众所周知为另外两种不同的模式。有些人将Yegge提出的系统称为“字符串[sic]类型”,这是另一种研究途径。

It's a really neat idea, and one that has a lot of merit in some applications, and a lot of faults in others. What you gain is essentially a very flexible means of building "types" at runtime, but you lose out on a lot of the languages strong-type checking to do it. The easiest way to implement it would be as a Dictionary<string,string>. Then you have to use casts to get your string values back out as actual values. The key to keeping such a design manageable is to never directly reference a property in code if you can avoid it. Stuff like theProtoObject["owner"] = "protoman" will kill you if the "canonical" name of that slot changes. It can also lead to issues like JavaScript (which uses this pattern underneath as it's object model) where if you misspell the key name, you'll add a new slot.

这是一个非常巧妙的想法,在某些应用程序中有很多优点,在其他应用程序中有很多缺点。你获得的本质上是一种在运行时构建“类型”的非常灵活的方法,但你会失去许多强类型检查的语言。实现它的最简单方法是作为Dictionary 。然后你必须使用强制转换来将你的字符串值作为实际值返回。保持这种设计可管理性的关键是如果可以避免,就永远不要直接引用代码中的属性。像theProtoObject [“owner”] =“protoman”这样的东西将会杀死你,如果该插槽的“规范”名称发生变化。它也可能导致像JavaScript这样的问题(在它下面使用这种模式作为它的对象模型),如果你拼错了键名,你将添加一个新的插槽。 ,string>

One very likely upgrade you'd probably make in a production system is to use some kind of specialized types for values, and some kind of "heavy key" for the key, so you can get a bit of extra typing and safety info on your model.

您可能在生产系统中进行的一次非常可能的升级是使用某种特殊类型的值,以及键的某种“重键”,这样您就可以获得一些额外的输入和安全信息。模型。

I've seen a few applications that use it. One surprising example hit me recently while looking up open source code in my industry: insurance quoting. OpenQuote is a very flexible project for quoting insurance of any general type. It's written in Java, but if you know C# it should read quite well. At the very heart of it, lies the Type object, which contains this bit of code:

我见过一些使用它的应用程序。最近一个令人惊讶的例子让我在查看行业中的开源代码时发现了我:保险报价。 OpenQuote是一个非常灵活的项目,用于报价任何一般类型的保险。它是用Java编写的,但是如果你知道C#就应该读得很好。它的核心是Type对象,它包含以下代码:

/** A dynamic collection of attributes describing type */
private List<Attribute> attribute = new ArrayList<Attribute>();

And what is an 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.

So basically Attribute is a kind of key-value pair containing a unique string ID (the field name) and a string value, and an enumeration of types combined with some regex to verify and process the values. In this way, it can store values of many types, and convert them back out into java values, while providing a bit of safety.

因此,基本上,Attribute是一种键值对,包含唯一的字符串ID(字段名称)和字符串值,以及与某些正则表达式相结合的类型枚举,以验证和处理这些值。通过这种方式,它可以存储多种类型的值,并将它们转换回java值,同时提供一些安全性。

It then goes on to build many domain specific model types on top of that core. So an insurance policy object can be treated as having a flexible, extensible list of benefits on it, which can added or removed or modified at runtime. Each benefit can have properties extended or reduced on them as well.

然后,它继续在该核心之上构建许多特定于域的模型类型。因此,保险政策对象可以被视为具有灵活,可扩展的利益列表,可以在运行时添加或删除或修改。每个好处都可以扩展或减少它们的属性。

So that's an example of the pattern in use, and a decent use case for it: insurance policies can be very flexible, at the whim of the underwriters up to the moment of sale, so a highly flexible model works well for it.

这就是使用模式的一个例子,也是一个不错的使用案例:保险单可以非常灵活,在承销商一直想到销售的时刻,所以一个高度灵活的模型可以很好地适应它。

The downsides are pretty much what Yegge outlines though. Performance can be bad, especially with a naive implementation. Type-checking and safety take a hit, and your objects are more difficult to reason about because you don't know for sure what properties are on them.

缺点是Yegge概述的内容。性能可能很糟糕,尤其是在实施过程中。类型检查和安全性受到打击,您的对象更难以推理,因为您不确定它们上面有哪些属性。

#2


The properties pattern is especially useful (or, it has been for me), when your want to make prototypes of objects or have a development structure that somewhat forces you to have an iterative deployment of your API/Interfaces.

当您想要制作对象原型或具有某种程度上迫使您对API /接口进行迭代部署的开发结构时,属性模式特别有用(或者,对我而言)。

If you start out with an idea of some properties of an object, then you make them. Later on you find (and you have anticipated this finding...) that your understanding of the subject area was not adequate, you make a new object design/behavior based on the prototype of the first object. And so forth. The wiki-page on the subject has a very good description of the subject in conjunction with static typed languages, but I would recommend that you looked into JavaScript or Lua if you're really serious with prototyping development. The properties of prototypes are not mutable in the static typed languages, and this fact will eventually bite you down the road.

如果你开始考虑一个对象的某些属性,那么你就可以创建它们。稍后您会发现(并且您已经预料到这一发现......)您对主题区域的理解不充分,您可以根据第一个对象的原型制作新的对象设计/行为。等等。关于这个主题的wiki页面与静态类型语言一起非常好地描述了这个主题,但如果你真的认真对待原型开发,我建议你研究一下JavaScript或Lua。原型的属性在静态类型语言中是不可变的,而这一事实最终会让你感到困惑。

Edit: Oh, and I see you link to an excellent post on the subject. Yegges use/explanation of the subject of course does dwarf my own. Please read it through a couple of times and the advantages/implications of the use of the properties pattern in a language like java should be very clear to you.

编辑:哦,我看到你链接到关于这个主题的优秀帖子。 Yegges使用/解释主题当然会使我自己相形见绌。请阅读几次,并且在java等语言中使用属性模式的优点/含义应该非常清楚。

Edit.2: link to wikipedia article: http://en.wikipedia.org/wiki/Prototype_pattern

Edit.2:链接到*文章:http://en.wikipedia.org/wiki/Prototype_pattern

#3


For someone using Java, as I read the article, I'd say you can't use the Properties Pattern on any projects, because quote:

对于使用Java的人,当我阅读这篇文章时,我会说你不能在任何项目中使用Properties Pattern,因为引用:

Java offers essentially zero support for the Properties Pattern.

Java为Properties Pattern提供了基本上零支持。

Same would be true for C# for the same reasons. I felt a little comforted when I came to that statement, because I sure wasn't finding any way to fit them together.

出于同样的原因,C#也是如此。当我谈到这个陈述时,我感到有点安慰,因为我确定没有找到任何方法让他们在一起。

So I'm not sure I understand your question. But thanks for the link - upvote the question for that alone. Now I understand some things I halfway intuited a little better.

所以我不确定我理解你的问题。但是感谢这个链接 - 单独提出问题。现在我理解了一些事情,我中途变得更好了。

#1


I've been digging into this pattern quite a bit myself lately, and I can tell you that finding information on it is pretty tough. Yegge calls it prototype or properties, but both of those are pretty heavily overused, and well known as two other, different patterns. Some people refer to systems like the one Yegge proposes as "stringly[sic] typed" so that's another avenue of research.

我最近一直在深入研究这种模式,我可以告诉你,找到它的信息非常困难。 Yegge将其称为原型或属性,但这两者都被严重过度使用,并且众所周知为另外两种不同的模式。有些人将Yegge提出的系统称为“字符串[sic]类型”,这是另一种研究途径。

It's a really neat idea, and one that has a lot of merit in some applications, and a lot of faults in others. What you gain is essentially a very flexible means of building "types" at runtime, but you lose out on a lot of the languages strong-type checking to do it. The easiest way to implement it would be as a Dictionary<string,string>. Then you have to use casts to get your string values back out as actual values. The key to keeping such a design manageable is to never directly reference a property in code if you can avoid it. Stuff like theProtoObject["owner"] = "protoman" will kill you if the "canonical" name of that slot changes. It can also lead to issues like JavaScript (which uses this pattern underneath as it's object model) where if you misspell the key name, you'll add a new slot.

这是一个非常巧妙的想法,在某些应用程序中有很多优点,在其他应用程序中有很多缺点。你获得的本质上是一种在运行时构建“类型”的非常灵活的方法,但你会失去许多强类型检查的语言。实现它的最简单方法是作为Dictionary 。然后你必须使用强制转换来将你的字符串值作为实际值返回。保持这种设计可管理性的关键是如果可以避免,就永远不要直接引用代码中的属性。像theProtoObject [“owner”] =“protoman”这样的东西将会杀死你,如果该插槽的“规范”名称发生变化。它也可能导致像JavaScript这样的问题(在它下面使用这种模式作为它的对象模型),如果你拼错了键名,你将添加一个新的插槽。 ,string>

One very likely upgrade you'd probably make in a production system is to use some kind of specialized types for values, and some kind of "heavy key" for the key, so you can get a bit of extra typing and safety info on your model.

您可能在生产系统中进行的一次非常可能的升级是使用某种特殊类型的值,以及键的某种“重键”,这样您就可以获得一些额外的输入和安全信息。模型。

I've seen a few applications that use it. One surprising example hit me recently while looking up open source code in my industry: insurance quoting. OpenQuote is a very flexible project for quoting insurance of any general type. It's written in Java, but if you know C# it should read quite well. At the very heart of it, lies the Type object, which contains this bit of code:

我见过一些使用它的应用程序。最近一个令人惊讶的例子让我在查看行业中的开源代码时发现了我:保险报价。 OpenQuote是一个非常灵活的项目,用于报价任何一般类型的保险。它是用Java编写的,但是如果你知道C#就应该读得很好。它的核心是Type对象,它包含以下代码:

/** A dynamic collection of attributes describing type */
private List<Attribute> attribute = new ArrayList<Attribute>();

And what is an 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.

So basically Attribute is a kind of key-value pair containing a unique string ID (the field name) and a string value, and an enumeration of types combined with some regex to verify and process the values. In this way, it can store values of many types, and convert them back out into java values, while providing a bit of safety.

因此,基本上,Attribute是一种键值对,包含唯一的字符串ID(字段名称)和字符串值,以及与某些正则表达式相结合的类型枚举,以验证和处理这些值。通过这种方式,它可以存储多种类型的值,并将它们转换回java值,同时提供一些安全性。

It then goes on to build many domain specific model types on top of that core. So an insurance policy object can be treated as having a flexible, extensible list of benefits on it, which can added or removed or modified at runtime. Each benefit can have properties extended or reduced on them as well.

然后,它继续在该核心之上构建许多特定于域的模型类型。因此,保险政策对象可以被视为具有灵活,可扩展的利益列表,可以在运行时添加或删除或修改。每个好处都可以扩展或减少它们的属性。

So that's an example of the pattern in use, and a decent use case for it: insurance policies can be very flexible, at the whim of the underwriters up to the moment of sale, so a highly flexible model works well for it.

这就是使用模式的一个例子,也是一个不错的使用案例:保险单可以非常灵活,在承销商一直想到销售的时刻,所以一个高度灵活的模型可以很好地适应它。

The downsides are pretty much what Yegge outlines though. Performance can be bad, especially with a naive implementation. Type-checking and safety take a hit, and your objects are more difficult to reason about because you don't know for sure what properties are on them.

缺点是Yegge概述的内容。性能可能很糟糕,尤其是在实施过程中。类型检查和安全性受到打击,您的对象更难以推理,因为您不确定它们上面有哪些属性。

#2


The properties pattern is especially useful (or, it has been for me), when your want to make prototypes of objects or have a development structure that somewhat forces you to have an iterative deployment of your API/Interfaces.

当您想要制作对象原型或具有某种程度上迫使您对API /接口进行迭代部署的开发结构时,属性模式特别有用(或者,对我而言)。

If you start out with an idea of some properties of an object, then you make them. Later on you find (and you have anticipated this finding...) that your understanding of the subject area was not adequate, you make a new object design/behavior based on the prototype of the first object. And so forth. The wiki-page on the subject has a very good description of the subject in conjunction with static typed languages, but I would recommend that you looked into JavaScript or Lua if you're really serious with prototyping development. The properties of prototypes are not mutable in the static typed languages, and this fact will eventually bite you down the road.

如果你开始考虑一个对象的某些属性,那么你就可以创建它们。稍后您会发现(并且您已经预料到这一发现......)您对主题区域的理解不充分,您可以根据第一个对象的原型制作新的对象设计/行为。等等。关于这个主题的wiki页面与静态类型语言一起非常好地描述了这个主题,但如果你真的认真对待原型开发,我建议你研究一下JavaScript或Lua。原型的属性在静态类型语言中是不可变的,而这一事实最终会让你感到困惑。

Edit: Oh, and I see you link to an excellent post on the subject. Yegges use/explanation of the subject of course does dwarf my own. Please read it through a couple of times and the advantages/implications of the use of the properties pattern in a language like java should be very clear to you.

编辑:哦,我看到你链接到关于这个主题的优秀帖子。 Yegges使用/解释主题当然会使我自己相形见绌。请阅读几次,并且在java等语言中使用属性模式的优点/含义应该非常清楚。

Edit.2: link to wikipedia article: http://en.wikipedia.org/wiki/Prototype_pattern

Edit.2:链接到*文章:http://en.wikipedia.org/wiki/Prototype_pattern

#3


For someone using Java, as I read the article, I'd say you can't use the Properties Pattern on any projects, because quote:

对于使用Java的人,当我阅读这篇文章时,我会说你不能在任何项目中使用Properties Pattern,因为引用:

Java offers essentially zero support for the Properties Pattern.

Java为Properties Pattern提供了基本上零支持。

Same would be true for C# for the same reasons. I felt a little comforted when I came to that statement, because I sure wasn't finding any way to fit them together.

出于同样的原因,C#也是如此。当我谈到这个陈述时,我感到有点安慰,因为我确定没有找到任何方法让他们在一起。

So I'm not sure I understand your question. But thanks for the link - upvote the question for that alone. Now I understand some things I halfway intuited a little better.

所以我不确定我理解你的问题。但是感谢这个链接 - 单独提出问题。现在我理解了一些事情,我中途变得更好了。