Zdaję sobie sprawę z różnic koncepcyjnych między agregacją a kompozycją. Czy ktoś może mi powiedzieć, jaka jest różnica w implementacji między nimi w Javie z przykładami?
Zdaję sobie sprawę z różnic koncepcyjnych między agregacją a kompozycją. Czy ktoś może mi powiedzieć, jaka jest różnica w implementacji między nimi w Javie z przykładami?
Odpowiedzi:
Kompozycja
final class Car {
private final Engine engine;
Car(EngineSpecs specs) {
engine = new Engine(specs);
}
void move() {
engine.work();
}
}
Zbiór
final class Car {
private Engine engine;
void setEngine(Engine engine) {
this.engine = engine;
}
void move() {
if (engine != null)
engine.work();
}
}
W przypadku kompozycji Silnik jest całkowicie zamknięty w samochodzie. Świat zewnętrzny nie może uzyskać odniesienia do silnika. Silnik żyje i umiera razem z samochodem. W przypadku agregacji samochód wykonuje swoje funkcje również za pośrednictwem silnika, ale nie zawsze jest on wewnętrzną częścią samochodu. Silniki można wymieniać, a nawet całkowicie usuwać. Nie tylko to, świat zewnętrzny może nadal mieć odniesienie do silnika i majstrować przy nim niezależnie od tego, czy jest w samochodzie.
new Engine(EngineSpecs)
wywołania, nawet jeśli nie było samochodu. Sposobem na osiągnięcie kompozycji jest stworzenie Engine jako klasy wewnętrznej, tak aby obiekt silnika był zawsze tworzony w odniesieniu do obiektu samochodu
Użyłbym fajnego przykładu UML.
Weź uniwersytet, który ma od 1 do 20 różnych wydziałów, a każdy wydział ma od 1 do 5 profesorów. Istnieje związek między uniwersytetem a jego wydziałami. Istnieje połączenie agregacyjne między wydziałem a jego profesorami.
Kompozycja to po prostu MOCNA agregacja, jeśli zniszczona zostanie uczelnia, to zniszczeniu powinny ulec również wydziały. Ale nie powinniśmy zabijać profesorów, nawet jeśli ich wydziały znikną.
W 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);
}
}
Coś wokół tego.
EDYCJA: przykład na żądanie
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());
}
}
Klasa uniwersytecka
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}";
}
}
Klasa działu
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}";
}
}
Klasa profesorska
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";
}
}
Implementacja jest dyskusyjna, ponieważ zależy od tego, w jaki sposób musisz poradzić sobie z tworzeniem, zatrudnianiem, usuwaniem itp. Nieistotne dla PO
W podanym adresie URL poniżej znajduje się świetne wyjaśnienie.
http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit
Proszę sprawdzić!!!
Prosty program do kompozycji
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);
}
}
Ustalmy warunki. Agregacja jest metatermem w standardzie UML i oznacza ZARÓWNO kompozycję, jak i wspólną agregację, nazywaną po prostu współużytkowaną . Zbyt często nazywa się to nieprawidłowo „agregacją”. To ZŁE, bo kompozycja też jest agregacją. Jak rozumiem, masz na myśli „udostępniony”.
Dalej od standardu UML:
złożone - wskazuje, że właściwość jest zagregowana w sposób złożony, tj. obiekt złożony jest odpowiedzialny za istnienie i przechowywanie złożonych obiektów (części).
Tak więc stowarzyszenie University to cathedras jest kompozycją, ponieważ katedra nie istnieje poza uniwersytetem (IMHO)
Precyzyjna semantyka współużytkowanej agregacji różni się w zależności od obszaru aplikacji i projektanta.
Oznacza to, że wszystkie inne skojarzenia można narysować jako wspólne agregacje, jeśli przestrzegasz tylko pewnych zasad własnych lub kogoś innego. Zajrzyj też tutaj .
Najpierw musimy porozmawiać o tym, jaka właściwie różnica między Aggregation
i Composition
ma być na tej samej stronie.
Agregacja to powiązanie, w którym podmiot powiązany może istnieć niezależnie od tego powiązania. Na przykład osoba może być powiązana z organizacją, ale może istnieć w systemie niezależnie.
natomiast
Kompozycja odnosi się do sytuacji, w której jeden z podmiotów powiązanych jest silnie powiązany z drugim i nie może istnieć bez istnienia drugiego. W rzeczywistości tożsamość tego podmiotu jest zawsze związana z tożsamością innego przedmiotu. Na przykład koła w samochodzie.
Teraz agregację można po prostu osiągnąć poprzez posiadanie własności jednego podmiotu w innym, jak poniżej:
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;
}
}
W przypadku kompozycji konieczne jest, aby obiekt zależny był zawsze tworzony z tożsamością skojarzonego z nim obiektu. Możesz użyć klasy wewnętrznej do tego samego.
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();
}
}
Należy pamiętać, że ten sam przypadek użycia może podlegać agregacji / kompozycji w zależności od scenariusza zastosowania. Na przykład sprawa Osoba-Organizacja może stać się składem, jeśli tworzysz aplikację dla osób pracujących w jakiejś organizacji, a przy rejestracji wymagane jest odniesienie do organizacji. Podobnie, jeśli utrzymujesz zapasy części samochodu, relacja Car-Wheel może być agregacją.
Agregacja a kompozycja
Agregacja zakłada związek, w którym dziecko może istnieć niezależnie od rodzica. Na przykład Bank i pracownik, usuń bank, a pracownik nadal istnieje.
mając na uwadze, że Kompozycja zakłada związek, w którym dziecko nie może istnieć niezależnie od rodzica. Przykład: człowiek i serce, serce nie istnieje oddzielnie od człowieka.
Relacja agregacji to relacja „ma-a”, a kompozycja jest relacją „częścią”.
Kompozycja to silne stowarzyszenie, podczas gdy agregacja jest słabym stowarzyszeniem.
Oba typy są oczywiście skojarzeniami i nie są tak naprawdę przypisane ściśle do takich elementów języka. Różnica polega na celu, kontekście i sposobie modelowania systemu.
Jako praktyczny przykład porównaj dwa różne typy systemów z podobnymi obiektami:
System rejestracji samochodów, który przede wszystkim śledzi samochody, ich właścicieli itp. Nie interesuje nas tutaj silnik jako odrębna jednostka, ale nadal możemy mieć atrybuty związane z silnikiem, takie jak moc i rodzaj paliwa. Tutaj Silnik może być złożoną częścią jednostki samochodowej.
System zarządzania warsztatem samochodowym, który zarządza częściami samochodowymi, serwisowaniem samochodów i wymianą części, może nawet kompletnych silników. Tutaj możemy nawet mieć zapasy silników i musimy śledzić je i inne części oddzielnie i niezależnie od samochodów. Tutaj Silnik może być zagregowaną częścią podmiotu samochodowego.
Sposób implementacji tego w swoim języku jest mniej istotny, ponieważ na tym poziomie takie kwestie jak czytelność są o wiele ważniejsze.