差异聚合,熟人和构图(由Gang Of Four使用)

dev*_*ull 7 oop design-patterns

我一直在阅读设计模式:可重复使用的面向对象软件的元素, 并得到了部分解释aggregationacquaintance.这是摘录(对不起,如果它太长了,但我认为解释这个问题很重要):

Consider the distinction between object aggregation and acquaintance and how
differently they manifest themselves at compile- and run-times. Aggregation
implies that one object owns or is responsible for another object. Generally we
speak of an object having or being part of another object. Aggregation implies
that an aggregate object and its owner have identical lifetimes.

Acquaintance implies that an object merely knows of another object. Sometimes
acquaintance is called "association" or the "using" relationship. Acquainted
objects may request operations of each other, but they aren't responsible for
each other. Acquaintance is a weaker relationship than aggregation and suggests
much looser coupling between objects.

...

Ultimately, acquaintance and aggregation are determined more by intent than by
explicit language mechanisms. The distinction may be hard to see in the
compile-time structure, but it's significant. Aggregation relationships tend to
be fewer and more permanent than acquaintance. Acquaintances, in contrast, are
made and remade more frequently, sometimes existing only for the duration of an
operation. Acquaintances are more dynamic as well, making them more difficult
to discern in the source code.
Run Code Online (Sandbox Code Playgroud)

对我来说令人困惑的部分是aggregation这里描述的具有以下特征composition- >组合对象包含/管理其他对象并且它们的生命周期被绑定.

另一方面acquaintance,该摘录中定义的特征是aggregation- >聚合对象只知道对象,但它不管理它们.

也是部分

Sometimes acquaintance is called "association" or the "using" relationship. 
Run Code Online (Sandbox Code Playgroud)

是混乱的,因为我认为两者aggregationcomposition是的形式associationaggregation作为较少耦合之一.

它可以是作者指的是aggregation作为acquaintancecomposition作为aggregation还是我失去了一些东西?

Hon*_*dek 7

我被教导的是你写的:

是否作者将聚合称为 熟人,将组合称为聚合,还是我遗漏了什么?

是的。我的理解是:

  1. 开始时,当您进行(粗略)分析时,请从关联方面考虑。在这个阶段通常就足够了。

  2. 稍后,当您描述(详细)设计时,您需要决定对象的所有权、它们的生命周期、实例化、清理等。

    更详细地指定关联 - 将它们分为两组:

    • 聚合(对象可以独立存在的更自由的关系)和
    • 组合(一个对象负责另一个对象的生命周期的更紧密的关系)。

然而,该术语的使用的是(四人帮的一个或我这里所描述的UML定义),所有条款均没有根据的关系整体的对象,而不是只有一个对象的一个方法使用一个局部变量(或参数,它只是局部变量的一种特殊类型)与另一个对象。

class Car {
    // There is an association between Car and RegistrationPlate.
    // This association is either composition or aggregation.
    // The type of association is *not* deferrable from the syntax here.
    // This is purely the design decision and depends on many things,
    // both technical and business logic.
    // In some countries the registration plates are movable among cars,
    // in others they are cancelled when you scrap the car.
    RegistrationPlate registrationPlate;

    // Technically, there is an association between Car and List
    // but we rarely call it like that. Tnstead we say
    // "there is one to many association between Car and Tyre"
    // and the List is viewed just as an implementation detail.
    List<Tyre> tyres;

    // There is neither association nor composition nor aggregation 
    // between Car and Engine and Fuel
    // but instead  Car <<uses>> Engine   and   Car <<uses>> Fuel.
    void doSomething(Fuel fuel) {
        Engine engine = new Engine();
        // (method parameter fuel is just a special case of a local method variable)
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在代码中,聚合和组合乍一看可能是一样的,尤其是在带有垃圾收集器的语言(如 Java、Kotlin 或 C#)中,程序员不必太在意清理[注1]。但是,不同之处在于对关联对象的生命周期的责任:

  • 组合的情况下,“容器”对象必须负责对其组件的所有必要清理。
  • 聚合的情况下,情况要复杂得多,因为聚合对象有(可以有)自己的生命,你必须非常小心地正确实施清理。

[注 1] 即使在具有垃圾收集器的语言中,您经常需要考虑清理,例如关闭打开的连接,释放文件句柄,并注意有效地丢失对对象的引用,使它们符合 GC 资格——不要忘记未使用集合中的对象,使用弱引用或其他技术。这超出了这个问题的范围。


vai*_*mar 2

组合:当一个类由另一个类的数据成员组成时。

Class A
{
   B ObjB;
}
Run Code Online (Sandbox Code Playgroud)

聚合:当一个类的方法在其范围内创建其他类的对象时

void A::methA()
{
   B* ObjB= new B();
   delete ObjB;
}
Run Code Online (Sandbox Code Playgroud)

熟悉/使用:当一个类的方法接受对另一个类的对象的引用作为参数时

void A:methA (B& objB) 
{

}
Run Code Online (Sandbox Code Playgroud)