简体   繁体   English

Java中聚合和组合的实现区别

[英]Implementation difference between Aggregation and Composition in Java

I'm aware of the conceptual differences between Aggregation and Composition.我知道聚合和组合之间的概念差异。 Can someone tell me the implementation difference in Java between them with examples?有人可以通过示例告诉我它们之间在 Java 中的实现差异吗?

Composition作品

final class Car {

  private final Engine engine;

  Car(EngineSpecs specs) {
    engine = new Engine(specs);
  }

  void move() {
    engine.work();
  }
}

Aggregation聚合

final class Car {

  private Engine engine;

  void setEngine(Engine engine) {
    this.engine = engine;
  }

  void move() {
    if (engine != null)
      engine.work();
  }
}

In the case of composition, the Engine is completely encapsulated by the Car.在组合的情况下,Engine 完全被 Car 封装。 There is no way for the outside world to get a reference to the Engine.外部世界无法获得对引擎的引用。 The Engine lives and dies with the car.发动机与汽车同生共死。 With aggregation, the Car also performs its functions through an Engine, but the Engine is not always an internal part of the Car.通过聚合,Car 还通过 Engine 执行其功能,但 Engine 并不总是 Car 的内部部分。 Engines may be swapped, or even completely removed.引擎可能会被交换,甚至完全移除。 Not only that, but the outside world can still have a reference to the Engine, and tinker with it regardless of whether it's in the Car.不仅如此,外界仍然可以参考Engine,不管它是否在Car中,都可以对其进行修补。

I would use a nice UML example.我会使用一个很好的 UML 示例。

Take a university that has 1 to 20 different departments and each department has 1 to 5 professors.以一所大学为例,它有 1 到 20 个不同的系,每个系有 1 到 5 名教授。 There is a composition link between a University and its' departments.大学与其院系之间存在组成联系。 There is an aggregation link between a department and its' professors.一个系和它的教授之间存在聚合链接。

Composition is just a STRONG aggregation, if the university is destroyed then the departments should also be destroyed.组成只是一个强大的集合,如果大学被摧毁,那么部门也应该被摧毁。 But we shouldn't kill the professors even if their respective departments disappear.但是,即使他们各自的部门消失了,我们也不应该杀死教授。

In java :在 Java 中:

public class University {

     private List<Department> departments;

     public void destroy(){
         //it's composition, when I destroy a university I also destroy the departments. they cant live outside my university instance
         if(departments!=null)
             for(Department d : departments) d.destroy();
         departments.clean();
         departments = null;
     }
}

public class Department {

     private List<Professor> professors;
     private University university;

     Department(University univ){
         this.university = univ;
         //check here univ not null throw whatever depending on your needs
     }

     public void destroy(){
         //It's aggregation here, we just tell the professor they are fired but they can still keep living
         for(Professor p:professors)
             p.fire(this);
         professors.clean();
         professors = null;
     }
}

public class Professor {

     private String name;
     private List<Department> attachedDepartments;

     public void destroy(){

     }

     public void fire(Department d){
         attachedDepartments.remove(d);
     }
}

Something around this.这周围的东西。

EDIT: an example as requested编辑:要求的一个例子

public class Test
{
    public static void main(String[] args)
    {
        University university = new University();
        //the department only exists in the university
        Department dep = university.createDepartment();
        // the professor exists outside the university
        Professor prof = new Professor("Raoul");
        System.out.println(university.toString());
        System.out.println(prof.toString());

        dep.assign(prof);
        System.out.println(university.toString());
        System.out.println(prof.toString());
        dep.destroy();

        System.out.println(university.toString());
        System.out.println(prof.toString());

    }


}

University class大学班

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class University {

    private List<Department> departments = new ArrayList<>();

    public Department createDepartment() {
        final Department dep = new Department(this, "Math");
        departments.add(dep);
        return dep;
    }

    public void destroy() {
        System.out.println("Destroying university");
        //it's composition, when I destroy a university I also destroy the departments. they cant live outside my university instance
        if (departments != null)
            departments.forEach(Department::destroy);
        departments = null;
    }

    @Override
    public String toString() {
        return "University{\n" +
                "departments=\n" + departments.stream().map(Department::toString).collect(Collectors.joining("\n")) +
                "\n}";
    }
}

Department class系类

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Department {

    private final String name;
    private List<Professor> professors = new ArrayList<>();
    private final University university;

    public Department(University univ, String name) {
        this.university = univ;
        this.name = name;
        //check here univ not null throw whatever depending on your needs
    }

    public void assign(Professor p) {
        //maybe use a Set here
        System.out.println("Department hiring " + p.getName());
        professors.add(p);
        p.join(this);
    }

    public void fire(Professor p) {
        //maybe use a Set here
        System.out.println("Department firing " + p.getName());
        professors.remove(p);
        p.quit(this);
    }

    public void destroy() {
        //It's aggregation here, we just tell the professor they are fired but they can still keep living
        System.out.println("Destroying department");
        professors.forEach(professor -> professor.quit(this));
        professors = null;
    }

    @Override
    public String toString() {
        return professors == null
                ? "Department " + name + " doesn't exists anymore"
                : "Department " + name + "{\n" +
                "professors=" + professors.stream().map(Professor::toString).collect(Collectors.joining("\n")) +
                "\n}";
    }
}

Professor class教授班

import java.util.ArrayList;
import java.util.List;

public class Professor {

    private final String name;
    private final List<Department> attachedDepartments = new ArrayList<>();

    public Professor(String name) {
        this.name = name;
    }

    public void destroy() {

    }

    public void join(Department d) {
        attachedDepartments.add(d);
    }

    public void quit(Department d) {
        attachedDepartments.remove(d);
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Professor " + name + " working for " + attachedDepartments.size() + " department(s)\n";
    }
}

The implementation is debatable as it depends on how you need to handle creation, hiring deletion etc. Unrelevant for the OP该实现是有争议的,因为它取决于您需要如何处理创建、招聘删除等。 与 OP 无关

A simple Composition program一个简单的组合程序

public class Person {
    private double salary;
    private String name;
    private Birthday bday;

    public Person(int y,int m,int d,String name){
        bday=new Birthday(y, m, d);
        this.name=name;
    }


    public double getSalary() {
        return salary;
    }

    public String getName() {
        return name;
    }

    public Birthday getBday() {
        return bday;
    }

    ///////////////////////////////inner class///////////////////////
    private class Birthday{
        int year,month,day;

        public Birthday(int y,int m,int d){
            year=y;
            month=m;
            day=d;
        }

        public String toString(){
           return String.format("%s-%s-%s", year,month,day);

        }
    }

    //////////////////////////////////////////////////////////////////

}
public class CompositionTst {

    public static void main(String[] args) {
        // TODO code application logic here
        Person person=new Person(2001, 11, 29, "Thilina");
        System.out.println("Name : "+person.getName());
        System.out.println("Birthday : "+person.getBday());

        //The below object cannot be created. A bithday cannot exixts without a Person 
        //Birthday bday=new Birthday(1988,11,10);

    }
}

There is a great explanation in the given url below.下面给定的 url 中有很好的解释。

在此处输入图片说明

http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit

Please check!!!请检查!!!

The difference is that any composition is an aggregation and not vice versa.不同之处在于任何组合都是聚合,反之亦然。

Let's set the terms.让我们设定条款。 The Aggregation is a metaterm in the UML standard, and means BOTH composition and shared aggregation, simply named shared .聚合是 UML 标准中的元术语,表示组合和共享聚合,简称为shared Too often it is named incorrectly "aggregation".它经常被错误地命名为“聚合”。 It is BAD, for composition is an aggregation, too.这是不好的,因为组合也是一种聚合。 As I understand, you mean "shared".据我了解,您的意思是“共享”。

Further from UML standard:进一步从 UML 标准:

composite - Indicates that the property is aggregated compositely, ie, 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.共享聚合的精确语义因应用领域和建模者而异。

Ie, 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 .也看看这里

In simple terms :简单来说 :

Both Composition and Aggregation are Associations.组合和聚合都是关联。 Composition -> Strong Has-A relationship Aggregation -> Weak Has-A relationship.组合 -> 强 Has-A 关系 聚合 -> 弱 Has-A 关系。

First we must talk about what actually the difference between Aggregation and Composition is to be on the same page.首先,我们必须讨论AggregationComposition之间的实际区别是在同一页面上。

Aggregation is an association where the associated entity may exist independent of the association.聚合是一种关联,其中关联的实体可以独立于关联而存在。 For example, a Person may be associated to an Organisation but he/she may have independent existence in the system.例如,一个人可能与一个组织相关联,但他/她可能在系统中独立存在。

whereas然而

Composition refers to a situation when one of the associated entities is strongly related to the other and cannot exist without the other's existence.组合是指当一个关联实体与另一个关联实体密切相关并且没有另一个实体存在就不能存在的情况。 In fact the identity of that entity is always associated with the identity of the other object.事实上,该实体的身份总是与另一个对象的身份相关联。 For example, wheels in a car.例如,汽车的轮子。

Now, aggregation can simply be achieved by holding a property of one entity in another as below:现在,聚合可以简单地通过将一个实体的属性保存在另一个实体中来实现,如下所示:

class Person {
    Organisation worksFor;
}

class Organisation {
    String name;
}

class Main {
    public static void main(String args[]) {

        //Create Person object independently
        Person p = new Person();

        //Create the Organisation independently
        Organisation o = new Organisation();
        o.name = "XYZ Corporation";

        /*
          At this point both person and organisation 
          exist without any association  
        */
        p.worksFor = o;

    }
}

For Composition it is necessary that the dependent object is always created with the identity of its associated object.对于组合,必须始终使用其关联对象的标识创建从属对象。 You can use an inner class for the same.您可以使用内部类。

class Car {
    class Wheel {
        Car associatedWith;
    }
}

class Main {
    public static void main() {
        //Create Car object independently
        Car car = new Car();

        //Cannot create Wheel instance independently
        //need a reference of a Car for the same.
        Car.Wheel wheel = car.new Wheel();
    }
}

Please note that the same use case may fall under aggregation/composition depending on the application scenario.请注意,根据应用场景,相同的用例可能属于聚合/组合。 For example, the Person-Organisation case may become composition if you are developing an application for people working in some organisation and the reference to organisation is must for sign up.例如,如果您正在为在某个组织中工作的人员开发应用程序,并且必须在注册时引用组织,则 Person-Organisation 案例可能会成为组合。 Similarly, if you are maintaining inventory for parts of a Car, Car-Wheel relationship can be aggregation.类似地,如果您要维护汽车零件的库存,则汽车-车轮关系可以是聚合的。

Aggregation vs Composition聚合与组合

Aggregation implies a relationship where the child can exist independently of the parent.聚合意味着一种关系,其中子项可以独立于父项而存在 For example, Bank and Employee, delete the Bank and the Employee still exist.例如银行和员工,删除银行和员工仍然存在。

whereas Composition implies a relationship where the child cannot exist independent of the parent.组合意味着一种关系,其中孩子不能独立于父母而存在 Example: Human and heart, heart don't exist separate to a Human.例子:人与心,心与人是分开存在的。

Aggregation relation is “has-a” and composition is “part-of” relation.聚合关系是“has-a”组合是“part-of”关系。

Composition is a strong Association whereas Aggregation is a weak Association.组合是强关联,而聚合是弱关联。

Both types are of course associations, and not really mapped strictly to language elements like that.这两种类型当然都是关联,并没有真正严格地映射到这样的语言元素。 The difference is in the purpose, context, and how the system is modeled.区别在于目的、上下文和系统建模方式。

As a practical example, compare two different types of systems with similar entities:作为一个实际示例,比较具有相似实体的两种不同类型的系统:

  • A car registration system that primarily keep track of cars, and their owners, etc. Here we are not interested in the engine as a separate entity, but we may still have engine related attributes, like power, and type of fuel.一个主要跟踪汽车及其所有者等的汽车注册系统。这里我们对作为单独实体的发动机不感兴趣,但我们可能仍然拥有与发动机相关的属性,例如功率和燃料类型。 Here the Engine may be a composite part of the car entity.这里引擎可能是汽车实体的复合部分。

  • A car service shop management system that manages car parts, servicing cars, and replace parts, maybe complete engines.一个汽车维修店管理系统,用于管理汽车零件、维修汽车和更换零件,可能是完整的发动机。 Here we may even have engines stocked and need to keep track of them and other parts separately and independent of the cars.在这里,我们甚至可能备有发动机,并且需要单独且独立于汽车来跟踪它们和其他部件。 Here the Engine may be an aggregated part of the car entity.这里引擎可能是汽车实体的聚合部分。

How you implement this in your language is of minor concern since at that level things like readability is much more important.您如何在您的语言中实现这一点是次要的问题,因为在该级别上,诸如可读性之类的事情更为重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM