Witam wszystkich, forumowiczów!
Dokładnie (wydaje mi się), że rozpracowałem ten schemat
Command
i chcę spróbować opowiedzieć o tym „własnymi słowami”.
Z Wikipedii możemy dowiedzieć się, że jej celem jest
stworzenie struktury, w której klasa wysyłająca i klasa odbierająca nie są od siebie bezpośrednio zależne. Organizowanie wywołania zwrotnego do klasy zawierającej klasę nadawcy . W zasadzie jest napisane jasno i poprawnie, ale tak jest w teorii. Jak to zrobić? I tu zaczynają się problemy, bo... opis nie jest już tak jasny i oczywisty. Dlatego już to rozgryzłem, postanowiłem opowiedzieć jak to zrozumiałem, może komuś się przyda: Na podstawie opisu przeznaczenia tego wzorca połączę opis z kodem, żeby było to bardziej przejrzyste, ponieważ w tej samej Wikipedii uogólnili to na wiele języków i dlatego opis jest oddzielony od przykładu. W tym wzorcu znajdują się cztery terminy, przyjmijmy je na razie za oczywiste: polecenia (
command
), odbiorca polecenia (
receiver
), osoba wywołująca polecenie (
invoker
) i klient (
client
). Wezmę przykład z tej samej Wikipedii, jest całkiem znośny.
Zadaniem jest klasa
Light
, która potrafi zrobić dwie rzeczy: włączyć światło i je wyłączyć. Jeśli chodzi o wzór, będzie to „odbiornik poleceń (
receiver
)”
public class Light{
public Light(){ }
public void turnOn(){
System.out.println("The light is on");
}
public void turnOff(){
System.out.println("The light is off");
}
}
Stwórzmy interfejs z jedną metodą
execute()
, która zostanie wykonana i która zostanie wywołana w oparciu o wzorzec „polecenie (
command
)”
public interface Command{
void execute();
}
Konieczne jest hermetyczne wykonanie umiejętności klasowych
Light
. W tym celu utworzymy klasy
TurnOnLightCommand
,
TurnOffLightCommand
które zaimplementują interfejs
Command
i które zaakceptują obiekt klasy w konstruktorze
Light
. I każdy z nich wykona tylko jedną akcję. Jeden wywoła metodę
turnOn()
, a drugi wywoła
turnOff()
.
public class TurnOnLightCommand implements Command{
private Light theLight;
public TurnOnLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOn();
}
}
public class TurnOffLightCommand implements Command{
private Light theLight;
public TurnOffLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOff();
}
}
Teraz nadszedł czas na utworzenie obiektu, który akceptuje metody obiektów hermetyzowanych
Light
. Jeśli chodzi o wzorzec, nazywa się to wywołującym polecenie (invokerem). Nazwijmy to
Switch
i pozwólmy przyjąć w konstruktorze zmienne
Command
, które będą użyte w tworzonych metodach
flipUp()
oraz
flipDown()
.
public class Switch {
private Command flipUpCommand;
private Command flipDownCommand;
public Switch(Command flipUpCommand,Command flipDownCommand){
this.flipUpCommand=flipUpCommand;
this.flipDownCommand=flipDownCommand;
}
public void flipUp(){
flipUpCommand.execute();
}
public void flipDown(){
flipDownCommand.execute();
}
}
I oczywiście stworzymy klasę, która użyje ich, aby zrozumieć, co się ogólnie dzieje. Nazywa się to metodą główną, w której odbędzie się cała akcja:
public class TestCommand{
public static void main(String[] args){
Light l=new Light();
Command switchUp=new TurnOnLightCommand(l);
Command switchDown=new TurnOffLightCommand(l);
Switch s=new Switch(switchUp,switchDown);
s.flipUp();
s.flipDown();
}
}
Dane wyjściowe będą następujące:
"The light is on"
"The light is off"
Gdzie to jest stosowane?
Cel jest jasny, co i dlaczego jest to potrzebne, a mianowicie: w sytuacji, gdy trzeba oddzielić konkretną realizację, jest to bardzo wygodne. Dzięki temu korzystanie z niektórych funkcji nie jest uzależnione od konkretnej implementacji i można je zmieniać bez szkody dla systemu. coś w tym stylu...) Piszcie swoje uwagi, podyskutujemy, może da się coś uprościć i lepiej opowiedzieć, jeśli zajdzie taka potrzeba, wszystko zredagujemy) Aby dla tych, którzy będą czytać po raz pierwszy, było to jak najbardziej jasne. Cóż, kto polubi artykuł, stawia „+” :) Dla mnie to ważne) Z biegiem czasu chcę pisać więcej o
Builder
,
Singleton
i nie tylko.
Zobacz także inne moje artykuły:
GO TO FULL VERSION