Я знаю о концептуальных различиях между агрегированием и композицией. Может ли кто-нибудь сказать мне разницу в реализации на Java между ними на примерах?
Я знаю о концептуальных различиях между агрегированием и композицией. Может ли кто-нибудь сказать мне разницу в реализации на Java между ними на примерах?
Ответы:
Сочинение
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();
}
}
В случае композиции Двигатель полностью заключен в машину. Внешний мир не может получить ссылку на Engine. Двигатель живет и умирает вместе с автомобилем. При агрегации автомобиль также выполняет свои функции через двигатель, но двигатель не всегда является внутренней частью автомобиля. Двигатели можно поменять местами или даже полностью снять. Более того, внешний мир все еще может иметь ссылку на Двигатель и работать с ним, независимо от того, находится ли он в Автомобиле.
new Engine(EngineSpecs)
вызова, даже если машины не было. Чтобы добиться композиции, нужно создать Engine как внутренний класс, чтобы объект Engine всегда создавался со ссылкой на объект Car
Я бы использовал хороший пример 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);
}
}
Что-то вокруг этого.
РЕДАКТИРОВАТЬ: пример по запросу
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());
}
}
Университетский класс
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";
}
}
Реализация спорна, поскольку она зависит от того, как вам нужно обрабатывать создание, удаление найма и т. Д. Не имеет отношения к OP
В приведенном ниже URL-адресе есть отличное объяснение.
http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit
Пожалуйста, проверьте!!!
Простая программа композиции
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:
составной - указывает на то, что свойство агрегировано составно, т. е. составной объект отвечает за существование и хранение составных объектов (частей).
Итак, ассоциация университета и кафедры - это композиция, потому что кафедра не существует вне университета (ИМХО).
Точная семантика совместной агрегации зависит от области приложения и разработчика.
Т.е. все остальные ассоциации можно нарисовать как общие агрегаты, если вы следуете только каким-то своим или чьим-то другим принципам. Также смотрите здесь .
Сначала мы должны поговорить о том, в чем на самом деле разница между Aggregation
и Composition
, чтобы быть на одной странице.
Агрегация - это ассоциация, при которой связанный объект может существовать независимо от ассоциации. Например, Человек может быть связан с Организацией, но он / она может иметь независимое существование в системе.
в то время как
Композиция относится к ситуации, когда одна из связанных сущностей сильно связана с другой и не может существовать без существования другой. Фактически идентичность этой сущности всегда связана с идентичностью другого объекта. Например, колеса в машине.
Теперь агрегации можно просто достичь, удерживая свойство одной сущности в другой, как показано ниже:
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;
}
}
Для композиции необходимо, чтобы зависимый объект всегда создавался с идентификатором связанного с ним объекта. Для этого можно использовать внутренний класс.
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();
}
}
Обратите внимание, что один и тот же вариант использования может подпадать под агрегацию / композицию в зависимости от сценария приложения. Например, случай «Человек-Организация» может стать составным, если вы разрабатываете приложение для людей, работающих в какой-либо организации, и для регистрации необходима ссылка на организацию. Точно так же, если вы ведете инвентарь для частей автомобиля, связь «автомобиль-колесо» может быть агрегированной.
Агрегация против композиции
Агрегация подразумевает отношения, в которых может существовать ребенок независимо от родителя. Например, Банк и Сотрудник, удалите Банк, и Сотрудник все еще существует.
тогда как композиция подразумевает отношения, при которых ребенок не может существовать независимо от родителя. Пример: Человек и сердце, сердце не существуют отдельно от Человека.
Отношение агрегации - это отношение «имеет», а композиция - отношение «часть из».
Состав - это сильная ассоциация, тогда как агрегирование - это слабая ассоциация.
Оба типа, конечно, являются ассоциациями и на самом деле не связаны строго с такими языковыми элементами. Разница заключается в цели, контексте и том, как моделируется система.
В качестве практического примера сравним два разных типа систем с похожими объектами:
Система регистрации автомобилей, которая в первую очередь отслеживает автомобили, их владельцев и т.д. Здесь Двигатель может быть составной частью автомобиля.
Система управления автосервисом, которая управляет автомобильными запчастями, обслуживает автомобили и заменяет детали, возможно, целые двигатели. Здесь у нас даже может быть запас двигателей, и нам нужно будет отслеживать их и другие части отдельно и независимо от автомобилей. Здесь Двигатель может быть агрегированной частью автомобиля.
То, как вы реализуете это на своем языке, не имеет большого значения, поскольку на этом уровне гораздо важнее такие вещи, как удобочитаемость.