Próbuję zrozumieć wzorzec strategii i zadaję sobie pytanie: czy klasa kontekstowa jest niezbędna, czy mogę ją pominąć bez uszczerbku dla celu wzorca?
Miałem wrażenie, że potrzebowałem jakiegoś rodzaju przełącznika do odczytu różnych typów plików, ale nie chciałem po prostu hakować czegoś, a później zajmować się refaktoryzacją (chociaż oczywiście zawsze zdarza się, że kod można refaktoryzować, ale pomysł był taki: spróbuj być jak najbardziej inteligentnym w projekcie ...):
Zdjęcie pochodzi z Wikipedii
Czy klient może delegować bezpośrednio do interfejsu strategii, czy też jest coś, czego mi brakowało, aby zrozumieć klasę kontekstu?
interface Reader {
// read information from file and fill data list field of Client
readFile();
}
class ExcelReader implements Reader{ /* */ }
class PdfReader implements Reader{ /* */}
class Client{
// strategic choice
Reader r;
// data list field
List<Data> data;
// Client Constructor
public Client(){
if(<file ends in .xls>)
r = new ExcelReader();
else
r = new PdfReader();
r.readFile();
}
}
Tak więc powyżej pokazano brak klasy kontekstu. Czy kod jest zgodny ze wzorem strategii?
design-patterns
strategy
rajstopy
źródło
źródło
Odpowiedzi:
W twoim przykładzie wywołanie kodu
readFile
jest częścią konstruktora klienta. Ta metoda jest „kontekstem”, którego szukasz . Wzorzec strategii nie potrzebuje dosłownie „klasy kontekstu”, a w pierwszej wersji kodu obiekt strategii (w twoim przypadku „Reader”) może znajdować się tylko w zmiennej lokalnej. Zwłaszcza, gdy można wywołać tylko jedną „metodę strategiczną” („readFile”).Jeśli jednak twoja baza kodu rośnie z jednej wersji do drugiej, nie jest prawdopodobne, aby wywoływano coraz więcej „strategicznych” metod, a decyzja, którą strategię zastosować i wykonanie „metod strategicznych” nastąpi w różnym czasie i w różnych miejscach w kodzie. Więc zaczynasz je refaktoryzować, aby zachować logikę w jednym miejscu. Doprowadzi to od razu do implementacji wyglądającej podobnie do diagramu w pytaniu.
źródło
Na pewno. Wzory są tylko wytycznymi. Nadal będziesz musiał je odpowiednio dostosować i zastosować do danego problemu. Osobiście rzadko pozwalam na ustawienie strategii w czasie wykonywania; częściej jest określany przy budowie lub rozwijany w fabryce.
Chociaż można również argumentować, że
setStrategy
jest prywatny, a mój zastrzyk po prostu używa wzoru, jak pokazano.źródło