Java 聚合与组合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/734891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:50:57  来源:igfitidea点击:

Aggregation versus Composition

javaoopuml

提问by Dave

I've had a hard time understanding the difference between composition and aggregation in UML. Can someone please offer me a good compare and contrast between them? I'd also love to learn to recognize the difference between them in code and/or to see a short software/code example.

我很难理解 UML 中组合和聚合之间的区别。有人可以给我一个很好的比较和对比吗?我也很想学习在代码中识别它们之间的区别和/或查看简短的软件/代码示例。

Edit: Part of the reason why I ask is because of a reverse documentation activity that we're doing at work. We have written the code, but we need to go back and create class diagrams for the code. We'd just like to capture the associations properly.

编辑:我问的部分原因是因为我们在工作中正在进行反向文档活动。我们已经编写了代码,但是我们需要返回并为代码创建类图。我们只想正确捕获关联。

采纳答案by Hexagon

The distinction between aggregation and composition depends on context.

聚合和组合之间的区别取决于上下文。

Take the car example mentioned in another answer - yes, it is true that a car exhaust can stand "on its own" so may not be in composition with a car - but it depends on the application. If you build an application that actually has to deal with stand alone car exhausts (a car shop management application?), aggregation would be your choice. But if this is a simple racing game and the car exhaust only serves as part of a car - well, composition would be quite fine.

以另一个答案中提到的汽车为例 - 是的,汽车尾气确实可以“独立”存在,因此可能不会与汽车组合在一起 - 但这取决于应用。如果您构建的应用程序实际上必须处理独立的汽车尾气(汽车商店管理应用程序?),聚合将是您的选择。但如果这是一个简单的赛车游戏,并且汽车尾气只是汽车的一部分——那么,构图就很好了。

Chess board? Same problem. A chess piece doesn't exist without a chess board only in certain applications. In others (like that of a toy manufacturer), a chess piece can surely not be composed into a chess board.

棋盘?同样的问题。只有在某些应用中没有棋盘,棋子才不存在。在其他情况下(例如玩具制造商的),棋子肯定不能组成棋盘。

Things get even worse when trying to map composition/aggregation to your favorite programming language. In some languages, the difference can be easier to notice ("by reference" vs. "by value", when things are simple) but in others may not exist at all.

尝试将组合/聚合映射到您最喜欢的编程语言时,情况会变得更糟。在某些语言中,差异可能更容易注意到(“按引用”与“按值”,当事情很简单时),但在其他语言中可能根本不存在。

And one last word of advice? Don't waste too much time on this issue. It isn't worth it. The distinction is hardly useful in practice (even if you have a completely clear "composition", you may still want to implement it as an aggregation due to technical reasons - for example, caching).

最后一句忠告?不要在这个问题上浪费太多时间。这不值得。这种区别在实践中几乎没有用(即使您有一个完全清晰的“组合”,由于技术原因,您可能仍希望将其实现为聚合 - 例如,缓存)。

回答by David M

Composition implies that the child objects share a lifespan with the parent. Aggregation doesn't. For example, a chess board is composed of chess squares - the chess squares don't really exist without the board. However, a car is an aggregation of parts - a car exhaust is still a car exhaust if it's not part of a car at the time.

组合意味着子对象与父对象共享一个生命周期。聚合没有。例如,棋盘由棋子组成——没有棋盘,棋子就真的不存在。然而,汽车是零件的集合——如果汽车尾气当时不是汽车的一部分,它仍然是汽车尾气。

回答by Chris Kessel

The example I learned was fingers to the hand. Your hand is composed of fingers. It owns them. If the hand dies, the fingers die. You can't "aggregate" fingers. You can't just go grab extra fingers and attach and detach them from your hand at will.

我学到的例子是手指到手。你的手是由手指组成的。它拥有它们。如果手死了,手指也会死。你不能“聚合”手指。您不能只是去抓住多余的手指,然后随意将它们从手上连接和分离。

The value here, from a design viewpoint, is often related to object lifespan as another poster said. Say you have a Customer and they have an Account. That Account is a "composed" object of the customer (at least, in most contexts I can think of). If you delete the Customer, the Account has no value on it's own so it would be deleted as well. The reverse is often true on object creation. Since an Account only has meaning in the context of a Customer, you'd have Account creation occur as part of Customer creation (or, if you do it lazily, it'd be part of some Customer transaction).

正如另一位海报所说,从设计的角度来看,这里的价值通常与对象的寿命有关。假设您有一个客户,他们有一个帐户。该帐户是客户的“组合”对象(至少在我能想到的大多数情况下)。如果您删除客户,则帐户本身没有任何价值,因此它也会被删除。在创建对象时,情况通常正好相反。由于 Account 仅在 Customer 的上下文中有意义,因此您将 Account 创建作为 Customer 创建的一部分(或者,如果您懒惰地这样做,它将成为某些 Customer 交易的一部分)。

It's useful in design to think about what objects own (compose) other objects vs. ones that just reference (aggregate) other objects. It can help determine where the responsibility lies for object creation/cleanup/updates.

在设计中考虑哪些对象拥有(组合)其他对象与那些只引用(聚合)其他对象的对象是很有用的。它可以帮助确定对象创建/清理/更新的责任所在。

As far as in the code, it's often hard to tell. Most everything in code is an object reference so it may not be obvious whether the referenced object is composed (owned) or aggregated.

就代码而言,通常很难说清楚。代码中的大部分内容都是对象引用,因此被引用的对象是组合(拥有)还是聚合可能并不明显。

回答by Chris May

In code terms, composition usually suggests that the containing object is responsible for creating instances of the component*, and the containing object holds the only long-lived references to it. So if the parent object gets de-referenced and garbage-collected, so will the child.

在代码方面,组合通常表明包含对象负责创建组件的实例*,并且包含对象持有对它的唯一长期引用。因此,如果父对象被取消引用和垃圾收集,子对象也将被取消引用。

so this code...

所以这个代码...

Class Order
   private Collection<LineItem> items;
   ...
   void addOrderLine(Item sku, int quantity){
         items.add(new LineItem(sku, quantity));
   }
}

suggests that LineItem is a component of Order - LineItems have no existence outside of their containing order. But the Item objects aren't constructed in the order - they're passed in as needed, and continue to exist, even if the shop has no orders. so they're associated, rather than components.

表明 LineItem 是 Order 的一个组成部分 - LineItems 在其包含的订单之外不存在。但是 Item 对象不是按顺序构建的——它们是根据需要传入的,并继续存在,即使商店没有订单。所以它们是关联的,而不是组件。

* n.b. the container is responsiblefor instanciating the component, but it might not actually call new...() itself - this being java, there's usually a factory or two to go through first!

* nb 容器负责实例化组件,但它实际上可能不会调用 new...() 本身——这是 java,通常首先要经过一两个工厂!

回答by erickson

The conceptual illustrations provided in other answers are useful, but I'd like to share another point I've found helpful.

其他答案中提供的概念性插图很有用,但我想分享我发现有用的另一点。

I've gotten some mileage out of UML for code generation, for source code or DDL for relational database. There, I have used composition to indicate that a table has a non-nullable foreign key (in the database), and a non-nullable "parent" (and often "final") object, in my code. I use aggregation where I intend a record or object to be able to exist as an "orphan", not attached to any parent object, or to be "adopted" by a different parent object.

我已经从 UML 中获得了一些用于代码生成、源代码或关系数据库 DDL 的里程。在那里,我在我的代码中使用组合来指示表具有不可为空的外键(在数据库中)和不可为空的“父”(通常是“最终”)对象。我使用聚合,我希望记录或对象能够作为“孤儿”存在,不附加到任何父对象,或者被不同的父对象“采用”。

In other words, I've used the composition notation as a shorthand to imply some extra constraints that might be needed when writing code for the model.

换句话说,我使用组合符号作为速记来暗示在为模型编写代码时可能需要的一些额外约束。

回答by Raj Rao

The example that I like: Composition:Water is a part-ofa Pond. (Pond is a composition of water.) Aggregation:Pond hasducks and fish (Pond aggregates ducks and fish)

我喜欢的例子: 组成:水是池塘的一部分。(池塘是水的组成。) 聚合:池塘鸭和鱼(池塘聚合鸭和鱼)

As you can see I have bolded "part-of" and "has", as these 2 phrases can typically point to what kind of a connection exists between the classes.

正如您所看到的,我将“part-of”和“has”加粗,因为这两个短语通常可以指出类之间存在什么样的联系。

But as pointed out by others, many times whether the connection is a composition or an aggregation depends on the application.

但正如其他人所指出的,很多时候连接是组合还是聚合取决于应用程序。

回答by vsingh

Composition and Aggregation are types of associations. They are very closely related and in terms of programming there does not appear to be much of a difference between the two. I will try to explain the difference between these two by java code examples

组合和聚合是关联的类型。它们非常密切相关,在编程方面,两者之间似乎没有太大区别。我将尝试通过java代码示例来解释这两者之间的区别

Aggregation: The object exists outside the other, is created outside, so it is passed as an argument (for example) to the constructor. Ex: People – car. The car is created in a different context and then becomes a person property.

聚合:对象存在于另一个之外,在外部创建,因此它作为参数(例如)传递给构造函数。例如:人 - 汽车。汽车是在不同的环境中创建的,然后成为个人财产。

// code example for Aggregation:
// reference existing HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer(HttpListener listener, RequestProcessor processor) {
    this.listener = listener;
    this.processor = processor;
  }
}

Composition: The object only exists, or only makes sense inside the other, as a part of the other. Ex: People – heart. You don't create a heart and then pass it to a person. Instead, the heart is created when the human is created.

构成:对象只存在,或者只在另一个内部有意义,作为另一个的一部分。例如:人——心。你不会创造一颗心,然后把它传给一个人。取而代之的是,当人类被创造出来时,心脏就被创造出来了。

// code example for composition:
// create own HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer() {
    this.listener = new HttpListener(80);
    this.processor = new RequestProcessor(“/www/root”);
  }
}

Explained here with an example Difference between Aggregation and Composition

这里用一个例子来解释聚合和组合之间的区别

回答by nxhoaf

As a rule of thumb: enter image description here

根据经验: 在此处输入图片说明

class Person {
    private Heart heart;
    private List<Hand> hands;
}

class City {
    private List<Tree> trees;
    private List<Car> cars
}

In composition(Person, Heart, Hand), "sub objects" (Heart, Hand) will be destroyed as soon as Person is destroyed.

在组合(Person、Heart、Hand)中,“子对象”(Heart、Hand)会在 Person 被销毁后立即销毁。

In aggregation(City, Tree, Car) "sub objects" (Tree, Car) will NOT be destroyed when City is destroyed.

在聚合(城市,树,汽车)中,“子对象”(树,汽车)在城市被销毁时不会被销毁。

The bottom line is, composition stresses on mutual existence, and in aggregation, this property is NOT required.

底线是,组合强调相互存在,在聚合中,不需要这个属性。

回答by read

It's so difficult to do a difference between aggregate relation and composite relation, but I'm going to take some examples, We have a house and rooms, here we have a composite relation, room it's a part of the house , and room life started with house life's and Will finish when house life's finish, room it's a part of the house, we talk about composition, like country and capital, book and pages. For aggregate relation example, take team and players, player can exist without team, and team is a group of players, and player life can started before team life's, if we speak about programming, we can create players and after we Will create team, but for composition no, we create room s inside of house . Composition ----> composite|composing. Aggregation -------> group | element

聚合关系和复合关系很难区分,但是我举一些例子,我们有房子和房间,这里我们有一个复合关系,房间是房子的一部分,房间生活开始了随着房屋生活的结束,当房屋生活结束时,房间是房屋的一部分,我们谈论构图,例如国家和首都,书籍和书页。以聚合关系为例,以团队和玩家为例,玩家可以没有团队而存在,而团队是一群玩家,玩家生活可以在团队生活之前开始,如果我们说编程,我们可以创建玩家,然后我们将创建团队,但是对于组合没有,我们在 house 内部创建了 room 。合成---->合成|合成。聚合 -------> 组 | 元素

回答by Gangnus

Let's set the terms. The Aggregation is a metaterm in the UML standard, and means BOTH composition and shared aggregation, simply named shared. To often it is named incorrectly "aggregation". It is BAD, for composition is an aggregation, too. As I understand, you mean "shared".

让我们设定条款。聚合是 UML 标准中的元术语,表示组合和共享聚合,简称为shared。通常它被错误地命名为“聚合”。这是不好的,因为组合也是一种聚合。据我了解,您的意思是“共享”。

Further from UML standard:

进一步从 UML 标准:

composite - Indicates that the property is aggregated compositely, i.e., the composite object has responsibility for the existence and storage of the composed objects (parts).

Composite - 表示该属性是复合聚合的,即复合对象负责组合对象(部分)的存在和存储。

So, University to cathedras association is a composition, because cathedra doesn't exist out of University (IMHO)

因此,大学与大教堂协会是一个组合,因为大学之外不存在大教堂(恕我直言)

Precise semantics of shared aggregation varies by application area and modeler.

共享聚合的精确语义因应用领域和建模者而异。

I.e., all other associations can be drawn as shared aggregations, if you are only following to some principles of yours or of somebody else. Also look here.

即,如果您只遵循您自己或其他人的某些原则,则可以将所有其他关联绘制为共享聚合。也看看这里