问题描述
来自GoF的设计模式:
From Design Pattern by GoF:
-
当对象A聚合对象B时,对象A是否必须具有引用对象B的字段成员?
when object A aggregates object B, must object A have a field member referencing object B?
当对象A认识对象B时,对象A是否必须具有引用对象B的字段成员?
when object A acquaints object B, must object A have a field member referencing object B?
当对象A时实例化对象B,对象A是否必须具有引用对象B的字段成员?
when object A instantiates object B, must object A have a field member referencing object B?
推荐答案
实例化创建一个对象实例(许多语言为此使用
new
关键字),而聚合则描述了对象(已经创建或实例化)之间的关系。
为防止混淆,我必须指出,本示例中使用的所有术语(例如 aggregation )都是在Martin Fowler的上下文中使用的,与FML相比,Martin Fowler引入了不同的定义或措辞Instantiation creates an object instance (many languages are using the
new
keyword for this) while aggregation describes the relationship between objects (that are already created or instantiated).To prevent confusion I have to point out that all terms used in this example like aggregation are used in the context of Martin Fowler, who has introduced a different definition or phrasing in contrast to the UML standard definition.从图中:
根据提供的图表,有两个类定义
Drawing
和Shape
称为 aggregation (聚合),根据定义,它描述了这两个对象的共享生存期。这意味着绘图
由任意数量的形状
组成,或更准确地说,是形状
是工程图
的一部分。当所有者的生命周期(绘图
)结束时,Shape
的生命周期也将结束:given are the two class definitions
Drawing
andShape
that have, according to your provided diagram, a relationship which is called aggregation, which by definition describes a shared lifetime of those two objects. This means aDrawing
'consists' of an arbitrary number ofShapes
or to be more precise aShape
is part of aDrawing
. When the lifetime of the owner (Drawing
) ends, then also the lifetime ofShape
will end:// The `Shape` class class Shape { ... } // The `Drawing`class that aggregates a single `Shape` class Drawing { // The reference to the instance of `Shape` private Shape shape; // The constructor public Drawing() { // Create an instance of `Shape`. // Because the relationship between `Drawing`and `Shape`is an aggregation the instantiation occurs inside the owners constructor (opposed to outside the owner object). this.shape = new Shape(); } }
因为
绘图之间的关系
和Shape
是聚合 类型为Shape $的实例c $ c>发生在所有者构造函数内部
(如果遇到 ,则在所有者对象外部)。Because the relationship between
Drawing
andShape
is an aggregation the instantiation of the typeShape
occurs inside the owners constructor (opposed to outside the owner object in case of acquaintance).该图显示的另一个关系是相识。 相识存在于类型
LineShape
和Color
的对象之间。这意味着LineShape
使用使用颜色
。Color
将独立于其拥有的LineShape
对象而生活。对象CreationTool
和LineShape
之间的虚线描述了实例化(创建)。这意味着CreationTool
创建LineShape
的实例。这是必需的,因为与 aggregation 熟人相对,它描述了两个对象的独立寿命。颜色
可以在其他Shape
对象之间共享。这要求LineShape
的相关对象(Color
对象)在所有者外部(而不是所有者的内部)实例化。构造函数,例如在 aggregation 场景中):The other relationship that is pictured by the diagram is the acquaintance. Acquaintance exist between the object of type
LineShape
andColor
. This means aLineShape
uses aColor
.Color
will live independent from its owningLineShape
object. The dashed line between the objectsCreationTool
andLineShape
describes an instantiation (create). This means thatCreationTool
creates the instance ofLineShape
. This is required since opposed to aggregation acquaintance describes an independent lifetime of both objects.Color
could be shared between otherShape
objects. This requires the related objects ofLineShape
, theColor
object, to be instantiated outside the owner (and not inside the owner's constructor like in an aggregation scenario):// The `LineShape` class class Color { ... } // The `LineShape`class that acquaints or associates with a single `Color` class LineShape { // The reference to the instance of `Shape` private Color color; // The constructor public LineShape(Color sharedColorInstance) { // Request an instance of `Shape` as constuctor parameter. // Because the relationship between `LineShape`and `Color`is an acquaintance the instantiation occurs outside the owners constructor (opposed to inside the owner object). this.color = sharedColorInstance; } } // The `CreationTool` class that creates an instance of `LineShape // and passes a shared instance of `Color`into the constructor. class CreationTool { Color color = new Color(); // Create the instance of `LineShape` // to satisfy the dashed line (relationship) in the diagramm LineShape firstLine = new LineShape(color); // To show the benefit of acquaintance a second instance of `LineShape` is created // using the same `Color` instance LineShape secondLine = new LineShape(color); // When firstLine's lifetime ends, // secondLine still has a valid instance of `Color` }
因为
LineShape
和Color
之间的关系是相识 实例化发生在所有者构造函数外部()(与所有者实例内部相反,例如在 aggregation 场景中)。这样,可以在多个所有者之间共享Color
的单个实例。Because the relationship between
LineShape
andColor
is an acquaintance the instantiation occurs outside the owners constructor (opposed to inside the owner object like in an aggregation scenario). This way a single instance ofColor
could be shared among multiple owners.如代码示例所示两种关系(或一般的关系)都需要引用,指向相关对象的引用要存储在拥有的对象中。唯一的区别是查看在何处创建拥有的对象。这种情况将描述这种关系的特殊形式:关联对象是实例化为所有者的 outside (熟人)还是实例化了所有者的 inside (聚合)?
这意味着您可以通过查看构造函数(或实例化)来区分这两种类型的关系:是传递给构造函数的相关对象实例,还是所有者的设置方法( acquaintance )或所有者的构造函数是无参数的还是无参数的( aggregation )?As you can see in the code examples both relations (or relations in general) require the reference, pointing to the related object(s), to be stored inside the owning object. The only difference is when looking at where the owned object was created. This circumstance will describe the special form of the relationship: was the related object instantiated outside the owner (acquaintance) or was it instantiated inside the owner (aggregation)?This means you can distinguish this two types of relationship by looking at the constructor (or instantiation): is the related object instance passed to the constructor or a setter method of the owner (acquaintance) or is the owner's constructor parameter-less or setter-less (aggregation)?
对于实例化,字段的要求是另一回事。可以说,当
CreationTool
实例化LineShape
时,它不需要字段来存储对该对象的引用。但是,对于Color
,CreationToolobject
可以存储对Color $的引用。 c $ c>实例,以便在创建新的
LineShape
实例时重复使用(共享),因为实例是Color $需要c $ c>来满足
LineShape
的构造函数。因此,如果首先需要一个字段来存储对创建者内部创建实例的引用,则该字段完全是可选的,并且取决于上下文。For instantiation the requirement of a field is a different story. We can say that when
CreationTool
instantiatesLineShape
it does not need a field to store a reference to this object. But in case of theColor
theCreationToolobject
can store the reference to theColor
instance in a field in order to reuse it (share it) when creating newLineShape
instances, since an instance ofColor
is needed to satisfy the constructor ofLineShape
. So if a field to store the reference to the created instance inside the creator is required is totally optional in first place and depends on the context.在此应提及要点是,如果是熟人,注入拥有对象实例的另一种方法是使用setter方法:
It should be mentioned at this point, that in case of acquaintance, another way to 'inject' the owned object instance is to use a setter method:
Color color = new Color(); LineShape shape = new LineShape(); shape.SetColor(color);
在可能的情况下,首选使用构造函数。
Using the constructor should be the prefered way whenever possible.
另一个说明,只是为了使其更加完整:当用于实现这种关系的语言具有自动内存管理(垃圾收集)功能时,生命周期控制就不再重要了。只要在M. Fowlers世界(或在UML世界的 aggregation )中,所有事物都成为熟人,因为只要存在对所拥有对象实例的任何引用(例如,公开实例(通过getter方法),垃圾收集器不会破坏该实例,并且它将继续存在-独立于所有者。
Another note, just to make it more complete: when the language used to implement such relationships has automatic memory management (garbage collection), then the aspect of lifetime controlling is no more relevant. Everything becomes acquaintance in M. Fowlers world (or aggregation in the UML world), since as long as there is any references stored to the owned object instance (e.g. when exposing the instance via a getter method), the garbage collector won't destruct this instance and it will continue to live - independent from the owner.
这篇关于当对象A实例化/聚集/认识对象B时,对象A是否必须具有引用对象B的字段成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!