Jakie jest zastosowanie Stowarzyszenia, Agregacji i Składu?

20

Przeszedłem przez wiele teorii na temat tego, czym jest enkapsulacja i trzy techniki jej wdrażania, którymi są Stowarzyszenie, Agregacja i Kompozycja.

Znalazłem :

Kapsułkowanie

Hermetyzacja jest techniką nadawania polom klasy prywatności i zapewniania dostępu do pól metodami publicznymi. Jeśli pole zostanie uznane za prywatne, nie będzie dostępne dla osób spoza klasy, ukrywając w ten sposób pola w klasie. Z tego powodu enkapsulacja jest również nazywana ukrywaniem danych.

Hermetyzację można opisać jako barierę ochronną, która zapobiega losowemu dostępowi do kodu i danych przez inny kod zdefiniowany poza klasą. Dostęp do danych i kodu jest ściśle kontrolowany przez interfejs.

Główną zaletą enkapsulacji jest możliwość modyfikowania naszego zaimplementowanego kodu bez łamania kodu innych osób, które używają naszego kodu. Dzięki tej funkcji Encapsulation zapewnia łatwość konserwacji, elastyczność i rozszerzalność naszego kodu.

Stowarzyszenie

Skojarzenie to relacja, w której wszystkie obiekty mają swój własny cykl życia i nie ma właściciela. Weźmy przykład Nauczyciela i Ucznia. Wielu uczniów może łączyć się z jednym nauczycielem, a pojedynczy uczeń może łączyć się z wieloma nauczycielami, ale nie ma własności między przedmiotami i obaj mają swój własny cykl życia. Oba mogą tworzyć i usuwać niezależnie.

Zbiór

Agregacja to wyspecjalizowana forma asocjacji, w której wszystkie obiekty mają swój własny cykl życia, ale istnieje własność, a obiekt podrzędny nie może należeć do innego obiektu nadrzędnego. Weźmy przykład wydziału i nauczyciela. Jeden nauczyciel nie może należeć do wielu działów, ale jeśli usuniemy dział, obiekt nauczyciela nie zostanie zniszczony. Możemy myśleć o tym jako o relacji „ma”.

Kompozycja

Kompozycja jest ponownie wyspecjalizowaną formą agregacji i możemy to nazwać relacją „śmierci”. Jest to silny rodzaj agregacji. Obiekt potomny nie ma swojego cyklu życia i jeśli obiekt nadrzędny zostanie usunięty, wszystkie obiekty potomne również zostaną usunięte. Weźmy jeszcze raz przykład relacji między Domem a pokojami. Dom może zawierać wiele pokoi, ale nie ma niezależnego życia pokoju i żaden pokój nie może należeć do dwóch różnych domów. Jeśli usuniemy dom, pokój zostanie automatycznie usunięty.

Pytanie brzmi:

Teraz są to przykłady z prawdziwego świata. Szukam opisu sposobu użycia tych technik w rzeczywistym kodzie klasy. Mam na myśli, po co stosować trzy różne techniki enkapsulacji , jak można je wdrożyć i jak wybrać, która technika ma być stosowana w danym momencie.

Sahil Mahajan Mj
źródło
1
Należy pamiętać, że agregacja, skład i stowarzyszenie nie są technikami wdrażania kapsułkowania. Hermetyzacja może również istnieć, nawet jeśli istnieje tylko jedna klasa / obiekt. Hermetyzacja jest po prostu niezbędną funkcją w Orientacji obiektowej, aby ukryć dane twojego obiektu.
Maxood
1
„Jeden nauczyciel NIE może należeć do wielu działów” naprawdę? Nie zauważyłeś, że Twój zasób zmodyfikował treść?
KNU,
Udało mi się użyć Composition do identyfikacji Roots Aggregate DDD i ich encji podczas projektowania opartego na domenie. Nowe zastosowanie starej konwencji.
Jonn

Odpowiedzi:

12

Rozróżnienie między skojarzeniem, agregacją i kompozycją, jak ją opisujesz, jest dziedzictwem sięgającym dawnych czasów ręcznego zarządzania pamięcią. Na przykład w C ++ pamięć wykorzystywana przez obiekty musi zostać ręcznie zwolniona, dlatego niezwykle ważne jest staranne zaprojektowanie cyklu życia złożonych obiektów. Podczas gdy wiele podręczników wciąż uczy różnicy między agregacją a kompozycją, jest to zasadniczo nieistotne przy programowaniu w środowiskach z automatycznym zarządzaniem pamięcią. Jeśli masz śmieci, wszystkie z nich są tylko kompozycją, kropką.

Z drugiej strony kapsułkowanie jest o wiele bardziej ogólną zasadą niż to, co opisujesz. Jest to przede wszystkim idea łączenia danych i funkcji, które działają na tych danych w jednym module. Jednym ze sposobów na wdrożenie tego jest zachowanie stanu modułu w stanie prywatnym i ujawnienie zmian tego stanu za pośrednictwem usług publicznych. Tak więc klient nie może uzyskać dostępu do stanu samodzielnie, ale musi poinformować moduł o swoim zamiarze, wysyłając wiadomości. Zatem enkapsulacja nie ogranicza się do obiektów, ale dotyczy również usług. W rzeczywistości jednym ze sposobów patrzenia na przedmioty jest patrzenie na nie jako na usługi.

Oto przykład enkapsulacji

public class Counter {
    private int n = 0;
    public int inc() { return n++; }
}

lub to samo przy użyciu funkcji lambda

var counter = (function() {
    var n = 0;
    var inc = function() { return n++; }
    return inc;
})();

W obu przypadkach dane, czyli zmienna n, są łączone razem z incdziałającą na nich funkcją . I nie ma możliwości, aby jakakolwiek inna funkcja mogła uzyskać dostęp n, dlatego mamy enkapsulowany moduł, który zapewnia liczenie jako usługę.

Uwaga: ujawnienie całego stanu wewnętrznego obiektu za pomocą akcesoriów jest w rzeczywistości naruszeniem hermetyzacji. Niestety, jest to tak powszechne naruszenie, że wielu pomyli je z dobrym projektowaniem obiektowym.

akuhn
źródło
2
Automatyczne zarządzanie pamięcią nie ma nic wspólnego z relacjami między obiektami. Sam diagram obiektowy mówi programiście, jak kodować klasy, ich interfejsy i metody zgodnie z wymaganiami rozważanego systemu.
Maxood
2
Istnieje również uwaga poza pamięcią. W projektowaniu danych lub serializacji. W składzie może być konieczne zastosowanie różnych ograniczeń klucza obcego w systemie RDBMS lub ewentualnie zmiana sposobu obsługi serializacji obiektu, jeśli ma on elementy podrzędne złożone i podrzędne elementy zagregowane lub powiązane obiekty.
Chris
8

Hermetyzacja jest techniką nadawania polom klasy prywatności i zapewniania dostępu do pól metodami publicznymi. Jeśli pole zostanie uznane za prywatne, nie będzie dostępne dla osób spoza klasy, ukrywając w ten sposób pola w klasie. Z tego powodu enkapsulacja jest również nazywana ukrywaniem danych.

    public class Test{

    private String name;

       private int age;

       public int getAge(){
          return age;
       }

       public String getName(){
          return name;
       }
    }

Patrz na to pytanie również .

Skojarzenie wskazuje związek między obiektami. np .: Komputer używa klawiatury jako urządzenia wejściowego.

Skojarzenie jest używane, gdy jeden obiekt chce, aby inny obiekt wykonał dla niego usługę.

Agregacja jest szczególnym przypadkiem stowarzyszenia. Kierunkowe powiązanie między obiektami. Kiedy obiekt „ma-a” inny obiekt, powstaje agregacja między nimi.

np .: Pokój ma stół, ale stół może istnieć bez pokoju.

    class Room {

      private Table table;

      void setTable(Table table) {
        this.table = table;
      }

    }

Kompozycja jest szczególnym przypadkiem agregacji. Skład jest bardziej restrykcyjny. Gdy istnieje kompozycja między dwoma obiektami, złożony obiekt nie może istnieć bez drugiego obiektu. Ograniczenie to nie występuje łącznie. np .: pokoje w domu, które nie mogą istnieć po zakończeniu życia domu.

    class House {

      private  Room room;

      House(Room roomSpecs) {
        room = new Room(roomSpecs);
      }

    }

Composition jest techniką projektową służącą do implementacji relacji typu ma w klasach przez dziedziczenie lub kompozycję obiektową w celu ponownego użycia kodu.

Jedną z najlepszych praktyk w programowaniu w Javie jest stosowanie kompozycji zamiast dziedziczenia

kapil das
źródło
Jak to odpowiada na zadane pytanie?
komar
1

Korzystanie z tych technik zwykle skutkuje praktykami projektowymi, takimi jak SOLID lub różne wzorce projektowe .

Celem stosowania wzorców, praktyk i tym podobnych jest opisanie rozwiązania konkretnego problemu, który jest również możliwy do utrzymania i rozszerzenia. Musisz tylko zdobyć wystarczającą ilość doświadczenia, aby powiedzieć, gdzie użyć danego wzoru lub techniki.

Euforyk
źródło
1

Szczerze mówiąc, uważam, że te pojęcia nauczane na uczelni mają swoje znaczenie w kontekście orientacji obiektowej i projektowania klas. Te koncepcje bardzo nam pomagają, jeśli chodzi o modelowanie systemu od podstaw. Skojarzenie, agregacja i skład należą wyłącznie do diagramu klas UML i są całkowicie niezależne od ograniczeń technologicznych, takich jak problemy z pamięcią.

Ponadto należy również wziąć pod uwagę wyższy poziom lub cele biznesowe modelowanego systemu. W naszym systemie rozważamy obiekty takie jak Dom i Pokój, ale nie można ich ściśle powiązać (poprzez kompozycję). Na przykład, jeśli modeluję system nieruchomości, być może będę musiał wiedzieć, jaki pokój należy do jakiego domu. Ale pozwólmy, że modeluję system ankiet lub spisów, w którym chcę wiedzieć, ile osób mieszka w każdym pokoju w domu w określonym obszarze, po prostu nie muszę wiązać pokoju z domem poprzez kompozycję.

Innym przykładem może być sad i pewien rodzaj owoców. Powiedzmy, że mogę rozważyć sad tylko wtedy, gdy sadzę w nim jabłonie. Najważniejsze jest to, że wymagania całego systemu mają duże znaczenie.

Enkapsulacja jest jednym z filarów projektowania obiektowego. Musisz połączyć swoje dane i operacje, które wykonasz na danych. musisz także ukryć pewne atrybuty swojego obiektu przed światem zewnętrznym, aby umożliwić temu obiektowi przetrwanie w prawidłowym stanie. Kiedy 2 obiekty wchodzą w interakcje, muszą one oddziaływać na siebie poprzez interfejs. I to właśnie zapewnia enkapsulacja podczas projektowania naszego systemu OO.

Oto, w jaki sposób te pojęcia są stosowane w kodzie:

STOWARZYSZENIE: Stowarzyszenie wskazuje związek między obiektami. Informuje programistę, jakie metody pisać w swoich klasach, aby umożliwić im interakcję. Możesz znaleźć kilka przykładów diagramów kodu i klas, aby zrozumieć powiązanie. W swoim przykładzie uczyć i Student, istnieje związek z nauczaniem i nauczał . Więc po prostu napiszesz zestaw metod (technicznie nazywany interfejsem), dzięki którym możesz dowiedzieć się, który uczeń ma nauczycieli i który nauczyciel ma uczniów. Skojarzenie umożliwia również modelarzowi systemu pomoc projektantowi bazy danych w zakresie atrybutów i pól, które muszą być przechowywane w bazie danych.

SKŁAD: Jeśli jeden obiekt jest integralną częścią innego obiektu, być może będę musiał wskazać ten związek w konstruktorze drugiego obiektu. Na przykład w twoim scenariuszu Domy i pokoje możemy napisać następujący kod na wypadek, gdybyśmy chcieli wiedzieć, który pokój należy do jakiego typu domu.

class House{
          string _HouseType;   
     public:    
    void setHouseType(string house_type)
     {
        this. _HouseType = house_type;
     } 

     string getHouseType()
    {
       return _HouseType;
    }
};



 House HouseObject = new House();


class Room{

 public: 
 Room(string HouseType) {
       this._HouseType = HouseObject.getHouseType();  //as in my system a room cannot exist without a house

 } 

};

Podczas wywoływania destruktorów obiektu programista upewni się również, że wywoływany jest również destuktor drugiego obiektu. To jest kluczowe.

AGREGACJA: Powiedzmy, że jeśli relacja między obiektami jest słaba, to dla programisty oznaczałoby to użycie zmiennej instancji w celu wskazania relacji. A następnie napisz funkcję mutatora (settera), aby podać wartość temu obiektowi z innego obiektu.

class Department{

 string dept_name;

public:
   void setDeptName(string name)
   {
        this.dept_name=name;
   }

   string getDeptName()
   {
        return dept_name; 
   }

};



 Department DepartmentObject = new Department();

class Teacher{

 string dept_name;

public:

  setDeptName(string name)
  {
     this.dept_name = DepartmentObject.getDeptName();  //You only need to invoje this method when needed (aggregation)
  }
}

};
Maxood
źródło
1

OK, przypiszmy to do niektórych podstawowych właściwości zamiast abstrakcyjnych pojęć, które mają sens dopiero wtedy, gdy zrozumiesz, co one oznaczają. Jak niektórzy komentatorzy nie zgadzam się z przyjętą odpowiedzią, mówię, że są to pojęcia niezależne od zarządzania pamięcią.

Kapsułkowanie

Chcesz ukryć złożoność przed klientem, publikując tylko to, co ważne z punktu widzenia klienta, co ułatwia klientowi. Jako bonus zyskujesz pewność, że nic nie zadziała z enkapsulowanym kodem. Tak długo, jak szanujesz interfejs i funkcjonalność, możesz przerabiać rzeczy i mieć pewność, że niczego nie zepsujesz. Zależność dotyczy tylko opublikowanego interfejsu.

Kapsułkowanie jest jednym z głównych filarów orientacji obiektowej. To nie jest wzór, to zasada i może mieć zastosowanie zarówno do logiki, jak i danych. Jest to po prostu podstawowa zaleta korzystania z klas, a nie coś, co wyraźnie widać w schemacie lub dokumencie projektowym.

Stowarzyszenie

Jest to bardzo luźna koncepcja, która opisuje po prostu zależność między obiektami. Jeden obiekt wie o istnieniu innego obiektu i może w pewnym momencie skorzystać z jego funkcjonalności. W diagramie skojarzenie ostrzega, że ​​istnieje zależność i że zmiana jednego obiektu może wpłynąć na drugi. Nie jest to technika stosowana, gdy masz jakiś problem do rozwiązania, jest raczej faktem życia, o którym powinieneś wiedzieć, kiedy tam jest. To jest związek. Jak faktura posiadająca właściwość Zamówienia. Zarówno zamówienie, jak i faktura mają swój własny cykl życia. Jedno dotyczy towarów, a drugie płatności, co zasadniczo czyni je niezależnymi, ale ważne jest, aby wiedzieć, za co płacone są towary.

Przechowywanie

Dodam to, ponieważ należy do serii i sprawi, że agregacja będzie bardziej znacząca. Nie słyszę już często tego terminu w kontekście SE, ale myślę, że nadal jest on użyteczny. Ograniczenie oznacza enkapsulację, ale dotyczy wyłącznie instancji obiektów prywatnych dla klasy zawierającej. Funkcjonalność zawartych obiektów jest selektywnie udostępniana za pośrednictwem interfejsów publicznych. Klasa zawierająca kontroluje cykl życia kontrolowanych obiektów. Używasz tego, gdy potrzebujesz niektórych funkcji istniejącej klasy, aby klasa zawierająca była funkcjonalna. Może to być parser XML, a klient klasy zawierającej może nigdy nie widzieć ani nie wiedzieć niczego związanego z XML. Jako metaforę pomyśl o zawartym obiekcie jak o pracowniku biurowym. Klienci nigdy nie spotykają tych ludzi, ale są oni potrzebni do świadczenia usługi.

Zbiór

Jest to bardzo podobne do ograniczania, z wyjątkiem kontroli cyklu życia i widoczności zagregowanych obiektów. Zagregowane obiekty są już dostępne w innym kontekście i są zarządzane przez inną jednostkę. Agregator oferuje jedynie fasadę, portal do zagregowanych obiektów. Gdy klient adresuje agregację, otrzymuje interfejs samego obiektu agregacji, a nie opakowanie wokół niego. Celem agregatu jest logiczne grupowanie rzeczy. Pomyśl o punkcie dostępu do usług lub innego obiektu opakowania.

Kompozycja

Wydaje mi się, że jest to bardziej współczesny termin powstrzymywania, być może dlatego, że powstał w popularnej książce stosunkowo niedawnego pochodzenia. Tam, gdzie ograniczanie koncentruje się na technicznych aspektach relacji między obiektami, kompozycja jest zwykle stosowana w kontekście decyzji projektowych, a dokładniej jako bardziej elastyczna alternatywa dla dziedziczenia.

Nie mówi wiele o naturze relacji między obiektami ani własności, wskazuje jedynie, że funkcjonalność jest realizowana poprzez połączenie funkcjonalności istniejących klas. Dlatego twierdzę, że nie należy do tej serii, ponieważ nie mówi nic o technicznych aspektach implementacji, gdzie robią to inni.

Martin Maat
źródło