Różnica implementacji między agregacją a kompozycją w Javie

103

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?

Rajath
źródło
3
Kliknij ten link, aby uzyskać odpowiedź na swoje posty [Różnica między agregacją a kompozycją] [1] [1]: stackoverflow.com/a/1468285/1353243
gks
możliwy duplikat Agregacja kontra kompozycja
Alex K
Zobacz także c-sharp-code-for-Association-
Agregation
Kiedy mamy jakikolwiek związek między obiektami, nazywa się to skojarzeniem. Agregacja i skład są wyspecjalizowaną formą stowarzyszenia. Kompozycja jest znowu wyspecjalizowaną formą Agregacji. javabench.in/2011/08/difference-between-association.html
Raúl
więcej odpowiedzi znajdziesz tutaj
hamed moosaei

Odpowiedzi:

222

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.

Anand
źródło
7
Świetny przykład! Pokazuje również kompozycję jako silne skojarzenie (samochód nie ma sensu bez silnika) i agregację jako słabe skojarzenie (samochód bez silnika ma sens, nawet nie potrzebuje go w swoim konstruktorze). Którego użyć? Zależy od kontekstu.
Federico Pugnali
@An i przykład, który podasz w Aggregation, czy nie jest to przykład zależności? Zależność jest słabszą formą relacji i pod względem kodu wskazuje, że klasa używa innej według parametru lub typu zwracanego.
OOkhan
@Anand: czy możesz wyjaśnić więcej, dlaczego powiedziałeś: w przypadku kompozycji nie ma możliwości, aby świat zewnętrzny uzyskał odniesienie do silnika, a przy agregacji świat zewnętrzny może mieć odniesienie do silnika? Czy możesz pokazać na przykładzie kodu, w jaki sposób świat zewnętrzny może lub nie może mieć odniesienia do silnika? dzięki
O Connor
9
To nie jest poprawny przykład. Świat zewnętrzny może mieć dostęp do obiektu wewnętrznego, ale jego tożsamość jest zawsze związana z obiektem zewnętrznym, podczas gdy w agregacji obiekt wewnętrzny może istnieć niezależnie, nawet jeśli nie było samochodu. W takim przypadku można nadal utworzyć silnik za pomocą 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
mickeymoon
@mickeymoon świetny chwyt. czy możesz wskazać nam lepszy przykład?
Gayan Weerakutti
20

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

TecHunter
źródło
Mam nadzieję, że nie otrzymam żadnego komentarza na temat niezainicjalizowanych list i żadnych konstruktorów. Napisałem to szybko, brakujące części to zdrowy rozsądek, ale na pytanie uzupełnię rozwiązanie
TecHunter
Dzięki! Twój przykład jest całkowicie jasny. Ale nie mogłem zrozumieć twojej ilustracji kodu. Czy możesz mi powiedzieć, jaka jest podstawowa różnica między nimi w implementacji? Jeśli muszę zaimplementować agregację lub kompozycję, jakich pojęć w Javie powinienem użyć?
Rajath
jest to dokładnie taka sama realizacja, jeśli mówić o klasy, lecz kompozycji powinna być odzwierciedlona poprzez sposób zarządzania instancje jak w moim edit
TecHunter
TecHunter, szukałem tego przykładu. Czy możesz również rozszerzyć kod java, aby zademonstrować skojarzenia na przykładzie Uniwersytetu. Jak przykład powinien działać w metodzie main (). (co może pokazać scenariusze tworzenia uniwersytetu i usuwania profesorów). Proszę o pomoc
deepakl.2000
@ deepakl.2000 można to zrobić na wiele sposobów. Powinieneś zdefiniować, która klasa ma moc. może to być profesor dołączający do uniwersytetu, a następnie jeden z wielu wydziałów, lub może to być uniwersytet zatrudniający profesora, a następnie proszący wydział o zapisanie się. chodzi o to, co ma większy sens dla twoich potrzeb.
TecHunter
4

W podanym adresie URL poniżej znajduje się świetne wyjaśnienie.

wprowadź opis obrazu tutaj

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

Proszę sprawdzić!!!

Rahul Saxena
źródło
Cześć Rahul, chociaż ten link może odpowiedzieć na pytanie, lepiej jest zawrzeć tutaj najważniejsze części odpowiedzi i podać link do odniesienia. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie. Spójrz tutaj: Dlaczego i w jaki sposób niektóre odpowiedzi są usuwane?
bummi
3

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

    }
}
Thilina Dimantha
źródło
Czy możesz również dodać działający kod java dla asocjacji i agregacji, a także wyjaśnić wszystkie scenariusze, jak wyjaśniono w kompozycji? 1. Scenariusze w skojarzeniu, jeśli zostaną usunięte? 2. Scenariusze w agregacji w przypadku usunięcia obiektu nadrzędnego?
deepakl.2000
3

Różnica polega na tym, że każda kompozycja jest agregacją, a nie odwrotnie.

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 .

Gangnus
źródło
3

W prostych słowach :

Zarówno skład, jak i agregacja są skojarzeniami. Kompozycja -> Silna relacja Has-A Agregacja -> Słaba relacja Has-A.

Kvk
źródło
2

Najpierw musimy porozmawiać o tym, jaka właściwie różnica między Aggregationi Compositionma 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ą.

mickeymoon
źródło
1

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.

shiv
źródło
0

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.

Użytkownik0
źródło