Composition over inheritance

0

Mam takie pytanie co do samej konwencji nazewnictwa. Czesto spotyka sie stwierdzenie composition over inheritance . Tylko moje pytanie jest takie czemu to nie jest aggregation over inheritance ? Przeciez kompozycja to jest jakby silna agreagacja gdzie np przez new tworzony jest obiekt innej klasy, a w agregacji przekazywany przez konstruktor.

0

Kwestia nomenklatury, zresztą "agregacja" zwykle wskazuje na powiązanie 1:n i mogłaby być myląca. Generalnie wiadomo że chodzi o to ze to Delegacja jest zawsze lepsza od dziedziczenia

0

Zawsze mnie zastanawiaja stwierdzenia majace w sobie 'zawsze', 'nigdy' itp.
Chcialbym zobaczyc system gdzie nie ma wcale dziedziczenia (w Javie, jako ze jestesmy w dziale Java). Jestem nawet sklonny stwierdzic, za szanowny Shalom takiego a) nigdy nie napisal b) sam takiego nie widzial
Stwierdzenia typu 'favor...over...', 'prefer...to...', 'strive for...' itp. maja to do siebie ze nie sa religijnymi dogmatami.

0

Krótko:

Dziedziczenie jest ok, nie ma co diabolizować.
Problemem jest to, że często się stosuje dziedziczenie do przekazywania dostępu do metod, które są de facto metodami utilsowymi. I w rezultacie mamy wielokrotne dziedziczenie, w której jedna z klas ma w sobie jakąś specyficzną metodę sortującą, druga z nich filtrującą, jeszcze inna zwraca jakiś konkretny wynik z kolekcji itp.
Druga sprawa to to, że ludzie po prostu mają tendencję do tworzenia zbyt rozbudowanych drzewek dziedziczenia, co w rezultacie prowadzi do ich zbytniego skomplikowania.

Przy composition over inheritance trudniej w takie pułapki wpaść, ot i cała tajemnica. Są oczywiście puryści językowi, którzy tłumaczą, że sprawdzenie dwóch klas z których jedna dziedziczy po drugiej jest trudniejsze od sprawdzenia dwóch klas niezależnych od siebie, ale to już inna historia.

Taka w sumie zagwozdka: czy stosowanie composition over inheritance nie wyklucza przypadkiem wzorca template method?

0

Taka w sumie zagwozdka: czy stosowanie composition over inheritance nie wyklucza przypadkiem wzorca template method?

Wręcz przeciwnie, template method oparty o dziedziczenie jest mocno ograniczony.

Wyobraź sobie że masz algorytm, który ma 4 kroki:

  • pobierz dane
  • wykonaj obliczenia
  • agreguj dane
  • wygeneruj wyjście

Chcemy tu użyć metody szablonowej bo algorytm jest zawsze taki sam, wymienne są tylko jego poszczególne "kroki", co więcej algorytm działa przy każdej kombinacji implementacji tych kroków. Gdybyś chciał to zrobić za pomocą dziedziczenia to okaże się to problematyczne. Template method oparty o dziedziczenie działa dobrze tylko jeśli nadpisujesz w podklasie wszystkie metody wołane przez metodę szablonową.
W sytuacji którą przedstawiłem dużo sensowniej i logiczniej jest zrobić 4 interfejsy, których implementacje będziemy przekazywać do klasy z metodą szablonową i ta metoda będzie delegować operacje do tych obiektów.

Pytanie brzmi: czy jeśli mamy tylko jedną metodę do nadpisania / nadpisujemy jedną klasą, to czy powinniśmy użyć dziedziczenia czy jednak zrobić delegację? ;)

0

@Szalom
Generalnie to było rozważanie mocno teoretyczne ;)
Chodzi o to, że takie rozwiązanie już jest niezgodne stricte z patternem template method jako takim, który przecież wymaga użycia dziedziczenia ;)

Tak czy inaczej:
IMO rozwiązywanie problemu przedstawionego przez Ciebie poprzez cztery metody abstrakcyjne jest łamaniem zasady pojedynczej odpowiedzialności i raczej - nawet nieświadomie - zastosowałbym zestaw czterech komponentów.

Ja sam stosuję się do zasady, że dziedziczenia używam wtedy, gdy jestem pewien że drzewko klas będzie odpowiednio płaskie (staram się nie przekraczać czterech warstw, tj. interfejs -> klasa abstrakcyjna -> konkretna#1 -> konkretna#2).

0
Shalom napisał(a):

W sytuacji którą przedstawiłem dużo sensowniej i logiczniej jest zrobić 4 interfejsy, których implementacje będziemy przekazywać do klasy z metodą szablonową i ta metoda będzie delegować operacje do tych obiektów.

Pytanie brzmi: czy jeśli mamy tylko jedną metodę do nadpisania / nadpisujemy jedną klasą, to czy powinniśmy użyć dziedziczenia czy jednak zrobić delegację? ;)

Pytanie brzmi - czy jest to nadal template method pattern? Moim zdaniem to jest poczworny strategy pattern...

0
wartek_no_log napisał(a):

Taka w sumie zagwozdka: czy stosowanie composition over inheritance nie wyklucza przypadkiem wzorca template method?

Czytalem raz opinie, nie pamietam gdzie i czyja, ale brzmiala mniej wiecej tak: design patterns are language limitations (na pewno 3 sekundowe googlowanie znajdzie autora i artykul). Jesli wiec mozna zrobic cos lepiej niz z jakims patternem poniewaz jezyk to wspiera, super, tak nalezy to zrobic. Nie plakalbym za template method pattern jesli byloby cos lepszego.
Dla przykladu, Clojure ma multi-methods ktore calkowicie eliminuja potrzebe na visitor pattern, ktory jest jednym z moich najbardziej nielubianych wzorcow (strasznie duzo trzeba pisac, visitor musi znac wszystkie podklasy albo byc strasznym generyczno-refleksyjnym potworem, itp.) - nikt w Clojure za nim nie placze ;d

0

Pytanie brzmi - czy jest to nadal template method pattern? Moim zdaniem to jest poczworny strategy pattern...

Moim zdaniem to nadal template method, bo masz w jednym miejscu zawarty abstrakcyjny algorytm z placeholedami na implementacje pewnych jego kroków. Jedyna różnica jest taka skąd ta implementacja się bierze - czy z implementacji abstrakcyjnej metody w podklasie czy w osobnym obiekcie.

0

Well, wikipedia mowi to w pierwszym zdaniu:
(...) the template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in a method, called template method, which defers some steps to subclasses.
Zatem wydaje mi sie ze nie jest to template method pattern, a jakas hybryda czegos z czyms. Ale masz racje, mozna roznie interpretowac i czepiam sie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1