Java中聚合和组合的实现差异

Java中聚合和组合的实现差异,java,relationship,aggregation,composition,Java,Relationship,Aggregation,Composition,我知道聚合和合成之间的概念差异。有人能用例子告诉我他们在Java中的实现差异吗 我会使用一个很好的UML示例 以一所拥有1至20个不同系的大学为例,每个系有1至5名教授。 大学与其各系之间存在着组成联系。 在一个系和它的教授之间有一个聚合链接 作文只是一个强大的集合,如果大学被摧毁,那么各系也应该被摧毁。但是我们不应该杀死教授,即使他们各自的系消失了 在java中: public class University { private List<Department> de

我知道聚合和合成之间的概念差异。有人能用例子告诉我他们在Java中的实现差异吗

我会使用一个很好的UML示例

以一所拥有1至20个不同系的大学为例,每个系有1至5名教授。 大学与其各系之间存在着组成联系。 在一个系和它的教授之间有一个聚合链接

作文只是一个强大的集合,如果大学被摧毁,那么各系也应该被摧毁。但是我们不应该杀死教授,即使他们各自的系消失了

在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);
     }
}
大学班级

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}";
    }
}
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}";
    }
}
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";
    }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.stream.collector;
公立大学{
私有列表部门=新建ArrayList();
公共部门{
最终部门dep=新部门(即“数学”);
部门。增加(dep);
返回dep;
}
公共空间销毁(){
System.out.println(“摧毁大学”);
//这是作文,当我毁掉一所大学的时候,我也毁掉了各个系。他们不能生活在我的大学之外
如果(部门!=null)
部门。forEach(部门::销毁);
部门=空;
}
@凌驾
公共字符串toString(){
返回“大学{\n”+
“departments=\n”+departments.stream().map(Department::toString.collect)(收集器.加入(“\n”))+
“\n}”;
}
}
系级

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}";
    }
}
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}";
    }
}
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";
    }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.stream.collector;
公共课系{
私有最终字符串名;
私有列表=新的ArrayList();
私立大学;
公共部门(大学,字符串名称){
这所大学=大学;
this.name=名称;
//检查这里大学不空根据你的需要扔任何东西
}
公共图书馆(p教授){
//也许在这里用一套
System.out.println(“部门招聘”+p.getName());
增加(p);
p、 加入(这个);
}
公共空间火灾(p教授){
//也许在这里用一套
System.out.println(“部门解雇”+p.getName());
删除(p);
p、 退出(这个);
}
公共空间销毁(){
//这里是聚集,我们只是告诉教授他们被解雇了,但他们仍然可以继续生活
系统输出打印(“销毁部门”);
professors.forEach(professor->professor.quit(this));
教授=空;
}
@凌驾
公共字符串toString(){
返回值==null
?“部门”+名称+“不再存在”
:“部门”+名称+“{\n”+
“professors=“+professors.stream().map(Professor::toString).collect(收集器.加入(“\n”))+
“\n}”;
}
}
教授班

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}";
    }
}
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}";
    }
}
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";
    }
}
import java.util.ArrayList;
导入java.util.List;
公共课教授{
私有最终字符串名;
私有最终列表attachedDepartments=new ArrayList();
公共教授(字符串名称){
this.name=名称;
}
公共空间销毁(){
}
公共图书馆(d部){
附件。添加(d);
}
公共图书馆(d部){
附件。移除(d);
}
公共字符串getName(){
返回名称;
}
@凌驾
公共字符串toString(){
返回“Professor”+姓名+“正在为“+attachedDepartments.size()+”部门工作)\n;
}
}
该实现是有争议的,因为它取决于您需要如何处理创建、雇用和删除等。与OP合成无关

final class Car {

  private final Engine engine;

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

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

final class Car {

  private Engine engine;

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

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

就合成而言,发动机完全由汽车封装。外部世界无法获得发动机的参考。发动机随汽车而生,随汽车而死。通过聚合,汽车也通过发动机执行其功能,但发动机并不总是汽车的内部部件。发动机可以更换,甚至可以完全拆下。不仅如此,外部世界仍然可以参考发动机,并对其进行修补,无论其是否在车内

一个简单的作曲程序

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);

    }
}
不同之处在于,任何组合都是聚合,反之亦然。 我们来定条件吧。聚合是UML标准中的一个元术语,表示组合和共享聚合,简称为共享。它经常被错误地命名为“聚合”。这是不好的,因为合成也是一种聚合。据我所知,你的意思是“共享”

进一步从UML标准:

复合-表示以复合方式聚合属性, i、 例如,复合对象对存在和存在负有责任 组合对象(部件)的存储

所以,大学到大教堂协会是一个组合,因为大教堂并不存在于大学之外(IMHO)

共享聚合的精确语义因应用程序区域和应用程序而异 建模师

也就是说,如果您只遵循您或其他人的某些原则,那么所有其他关联都可以绘制为共享聚合。另请看。

简单地说:

组合和聚合都是关联。 组合->强Has-A关系
聚合->弱Has-A关系。

下面给出的url中有一个很好的解释


请检查

首先,我们必须讨论
聚合
合成
之间的实际区别是什么

聚合是一种关联