Niedawno zacząłem szukać Wzorów projektowych i jedna rzecz, którą koduję, idealnie pasuje do wzorca Strategii, z wyjątkiem jednej małej różnicy.
Zasadniczo niektóre (ale nie wszystkie) z moich algorytmów wymagają przekazania dodatkowego parametru lub dwóch.
Więc albo będę musiał
- przekazuję im dodatkowy parametr, gdy wywołuję ich metodę obliczania
lub
- przechowuj je jako zmienne w klasie ConcreteAl Algorytm i być w stanie je zaktualizować, zanim wywołam algorytm.
Czy istnieje wzorzec projektowy dla tej potrzeby / Jak mogę to zrealizować, pozostając przy schemacie strategicznym?
Rozważałem przekazanie obiektu klienta do wszystkich algorytmów i zapisanie tam zmiennych, a następnie użycie go tylko wtedy, gdy dany algorytm tego potrzebuje. Myślę jednak, że jest to zarówno niewygodne, jak i pokonuje sens wzorca strategii.
Żeby było jasne, wdrażam w Javie, więc nie mam luksusu opcjonalnych parametrów (które by to ładnie rozwiązały).
źródło
Odpowiedzi:
Samuelu, czy można zawrzeć parametr, który każda ze strategii uwzględnia w jednej wspólnej klasie, a następnie rozszerzyć tę wspólną klasę Parameter, aby dodać więcej zachowań, których niektóre twoje strategie potrzebują?
Na przykład
Następnie zdefiniuj hierarchię strategii:
nazwij powyższą strategię jako:
myNormalStrategyInstance.myStrategyMethod(strategyParameter);
wywołaj powyższą strategię, przekazując
SpecialStrategyParameter
instancję zamiast:mySpecializedStrategy.myStrategyMethod(specialStrategyParameter);
Zaktualizuj, jeśli coś nie jest jasne. Z przyjemnością wyjaśnimy / wyjaśnimy.
źródło
StrategyParameter
wszystkie możliwe parametry, tak jak DTO. Niektóre wdrożenia strategii mogą je zignorować. W niektórych przypadkach jest to najlepsze podejście. Kontekst jest królem dla tego rodzaju problemów.Musisz wyjaśnić swoją strategię .
Wszystko zależy od tego, jak korzystasz z algorytmów. Aby klasa klienta mogła używać zamiennie różnych implementacji strategii, wszystkie muszą mieć wspólną abstrakcję . Jeśli nie są zgodne z tym samym interfejsem, być może potrzebujesz różnych abstrakcji .
Wcześniej stosowałem konfigurowalne strategie, w których parametryzujesz konkretne klasy konstrukcyjne:
Teraz ktoś nadal musi utworzyć instancję tej klasy i przekazać ją klientowi. Ale twój klient musi tylko wiedzieć o
Strategy
interfejsie.Działa również, jeśli twoja metoda strategii przyjmuje parametry, ale wtedy twój klient wie o tych parametrach i przekazuje je do wszystkich implementacji, z którymi współpracuje.
źródło
Tak długo, jak podpis jest wyraźnie zdefiniowany w interfejsie, nadal jest zgodny ze wzorem strategii.
Wzory jak napisane są absolutnie najprostszą formą, która nadal wykazuje oczekiwane zachowanie, więc możesz je upiększyć, o ile zachowasz pierwotne zamiary. To oczywiście zakłada, że chcesz podążać za tym wzorem. Nie ma sensu używać wzoru, jeśli nie pasuje, lub po prostu dlatego, że tam jest, ale w twoim przypadku myślę, że nic ci nie jest.
źródło
rozszerzając powyższą odpowiedź dostarczoną przez peakit - możesz użyć abstrakcji. Używam tutaj kodu peakit -
Interfejs MyStrategy { abstract void myStrategyMethod (parametr StrategyParameter); }
klasa MyNormalStrategy rozszerza MyStrategy {publiczne zastąpienie void myStrategyMethod (parametr StrategyParameter) {// implementuj logikę tutaj}}
klasa MySpecializedStrategy rozszerza MyStrategy {publiczne zastąpienie void myStrategyMethod (parametr StrategyParameter, ExtraStrategyParameter extraParameter) {// implementuj logikę tutaj} }
Jeśli dobrze rozumiem twoje pytanie, chciałeś przekazać dodatkowy parametr do niektórych algorytmów, prawda? Daj mi znać, jeśli tego właśnie szukasz?
źródło
Jeśli spojrzysz na książkę wzorców projektowych, nie jest błędem samo w sobie, że istnieje SimpleStrategy, która używa mniej lub wcale nie przekazanych parametrów, lub że parametry są jednym uniwersalnym / najmniejszym wspólnym mnożnikiem. Wybór projektu polega na tym, czy to cię boli pod względem dodatkowego przetwarzania, które ostatecznie nie jest używane.
źródło