![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 872 Pomógł: 94 Dołączył: 31.03.2010 Ostrzeżenie: (0%) ![]() ![]() |
Cześć, mam problem z decyzją, czy zastosować kompozycję czy dziedziczenie.
Stan aktualny: MatchInterface (interface) Match (class, implementuje MatchInterface) Chciałbym stworzyć nowy rodzaj Matcha (dopasowania), który zyskuje nową metodę "getName()" oraz argument konstruktora względem klasy Match. W tym celu dodałem nowy interface oraz klasę: NamedMatchInterface (interface dziedziczący po MatchInterface dodający nową metodą getNamed()) NamedMatch (class, implementuje NamedMatchInterface) Proszę nie zwracać uwagi na na nazewnictwo, jest to PSR ale nie wykluczone, że zmienię tę konwencję, bo mi trochę nie odpowiada. Moje pytanie brzmi: klasa "NamedMatch" powinna dziedziczyć po klasie "Match" i dodawać nową metodę oraz nadpisać konstruktor, czy jednak zastosować kompozycję? Z punktu widzenia testów jednostkowych oraz możliwości rozwoju skłaniam się do kompozycji, jednak chciałbym poznać Wasze zdanie. Edit: Niby to powinna być kompozycja, bo dochodzi nowa metoda, jednak 4 inne metody są identyczne jak w klasie Match i w przypadku zastosowania kompozycji będą po prostu proxowane do klasy Match. Ten post edytował lukaskolista 4.12.2016, 14:24:52 |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 1 590 Pomógł: 185 Dołączył: 19.04.2006 Skąd: Gdańsk Ostrzeżenie: (0%) ![]() ![]() |
Cytat czy zastosować kompozycję czy dziedziczenie. - pytanie dziwne, bo to dwa przeciwstawne wzorce.I "część wspólna" to nie jest powód, by dziedziczyć czy tym bardziej tworzyć kompozycję. To wg mnie podstawowy błąd. Tak się robiło w XIX wieku, gdzie programy były statyczne i pisane z myślą o tym, że nigdy nie będą zmieniane, W dobie adżajlów używanie wzorców, które bazują na bardzo sztywnej relacji pomiędzy obiektami (jak dziedziczenie) jest sztuką dla sztuki. Dziedziczenie pięknie wygląda tylko w teorii, w praktyce zaraz zmieni się w stertę antywzorców takich jak jojo czy callsuper. Trzeba zawsze dążyć do tego, aby implementacja była jak najprostsza i jak najbardziej skalowalna. Jeśli mamy część wspólną to wystarczy: - utworzyć klasę np. MatchService (część wspólna) - dostarczyć ją do klas Match i NamedMatch (które implementują część wspólną, oraz korzystają z jej funkcjonalności) Czyli prosta fasada. Dzięki temu możemy dowolnie rozwijać każdą klasę nie martwiąc się, że np. złamiemy kontrakt klasy nadrzędnej. Wiele frameworków ma wręcz zautomatyzowane tworzenie fasad, gdzie fasadę wpisuje się w .cfg i już mamy gotowy do użycia obiekt Match lub NamedMatch wraz ze wszystkimi zależnościami. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 12.10.2025 - 18:57 |