Czy dziedziczenie kontekstu, jak pokazuje przykład kaczki Head First Design Patterns, nie ma znaczenia dla wzorca strategii?

10

W Head First Design Patterns uczy wzorca strategii na przykładzie kaczki, w którym różnym podklasom kaczki można przypisać określone zachowanie w czasie wykonywania. Z mojego rozumienia celem wzorca strategii jest zmiana zachowania pojedynczego obiektu w czasie wykonywania, jednak używają one dziedziczenia Kaczki, aby zmienić zachowanie różnych typów Kaczek.

Wzór strategii

Stosowność?

Czy dziedziczenie kontekstu Kaczki nie ma znaczenia dla wzorca strategii, czy też różne typy Kaczek, a także ich zachowania są dobrym powodem do zastosowania wzorca strategii? Czy sytuacje, w których musisz się różnić, stanowią dobry powód do zastosowania wzorca strategii? Dlaczego mieliby to uwzględniać jako przykład wzorca strategii?

Prostszy przykład

Czy mogę jeszcze bardziej uprościć ten przykład, mając po prostu klasę Duck (bez klas pochodnych)? Następnie podczas implementacji jednego obiektu kaczki można mu przypisać różne zachowania w zależności od pewnych okoliczności, które nie są zależne od jego własnego typu obiektu. Na przykład: FlyBehavior zmienia się w zależności od pogody lub QuackBehavior zmienia się w zależności od pory dnia lub tego, jak głodna jest kaczka. Zdaję sobie sprawę, że rozwiązałoby to inny problem niż ten opisany w książce, ale szukam odpowiedniego wzorca strategii, na którym można się oprzeć.

Czy mój powyższy przykład również stanowiłby wzór strategii?

Edytować:

Udało mi się znaleźć 2 prostsze przykłady wzorców strategii, które ściślej stosują się do bycia wzorcami strategii bez dziedziczenia kontekstu: Hunter.java i solver.py .

Korey Hinton
źródło

Odpowiedzi:

7

Tak, myślę, że jesteś na dobrej drodze. Klasa wykorzystująca wzorzec strategii nie musi być podklasą. Wzorzec strategii stanowi alternatywę dla dziedziczenia w celu ponownego użycia kodu. Wraca to do jeszcze szerszego porównania dziedziczenia w stosunku do składu.

Od wzorców projektowych: elementy wielokrotnego użytku OOP, do którego użyłbyś wzorca strategii

  • Unikaj eksplozji podklas (z powodu kombinacji zachowań)
  • Jeśli chcesz zamienić zachowanie w czasie wykonywania

Jeśli zastosowałeś dziedziczenie do wdrożenia zachowań Quack i Fly, to wszystkie te podklasy przedstawiałyby wszystkie kombinacje zachowań.

  • FlyableQuackableDuck
  • FlyableSqeakableDuck
  • FlyableMuteDuck
  • NoFlyQuackableDuck
  • NoFlySqueakableDuck
  • NoFlyMuteDuck

Posiadanie tak wielu podklas utrudnia utrzymanie, dlatego w tym przypadku preferowany jest wzorzec strategii. Potrzebujesz tylko dwóch właściwości, które zawierają Flyability i Quackability i możesz je mieszać i łączyć bez tworzenia nowych klas.

Wspomniałeś już również o korzyściach płynących z działania w czasie, gdyby pogoda zmieniła właściwość Fly kaczki, która mogłaby zostać zastąpiona obiektem NoFly ze względu na warunki.

Jest to zgodne z poradą, aby w miarę możliwości preferować kompozycję zamiast dziedziczenia.

Despertar
źródło
1

Czy mogę jeszcze bardziej uprościć ten przykład, mając po prostu klasę Duck (bez klas pochodnych)? Następnie podczas implementacji jednego obiektu kaczki można mu przypisać różne zachowania w zależności od pewnych okoliczności, które nie są zależne od jego własnego typu obiektu.

Na pewno. Aby uzyskać inspirację, zapoznaj się z analizą i projektowaniem zorientowanym obiektowo . Jest „Gitary Ricka” pokazujące eksplozję (muzycznych) podklas instrumentów . Aby temu zaradzić, całe to zróżnicowane zachowanie jest zawarte w klasie „specyfikacji”, z zachowaniem zasady kapsułkowania tego, co się zmienia .

Fabryka abstrakcyjna - konstrukcja kontekstowa

Oto wzór . BTW, zauważ, że używa samej strategii.

Koncentrowanie się na koncepcji, a nie implementacji ... Być może istnieje „WeatherFactory”, który buduje obiekty specyfikacji w oparciu o warunki słoneczne lub deszczowe itp.

Możesz mieć „fabryki fabryk”, aby zająć się budowaniem tych rzeczy „NoFlyInFogQuackableMallard”. I rzeczywiście o to chodzi w wzorcu Fabryki Abstrakcyjnej. Może więc DuckFactory, aby stworzyć ogólne typy kaczek, a następnie WeatherFactory, aby nadać mu charakterystyczne dla mglistych zachowań pogodowych.

radarbob
źródło