Mateusz Wajnberger
Strategia – behawioralny wzorzec projektowy
Dla lepszego zobrazowania i zapamiętania wybranego wzorca projektowego posłużymy się dwoma postaciami z kultowego serialu „The Office”. Michael Scott – Kierownik Biura oraz Dwight Schrute – Assistant to the Regional Manager :)) Zostanie ustalona strategia wydawania najważniejszych poleceń podczas pracy w biurze.
Kod przed implementacją
Tworzymy klasę asystent z metodą publiczną o nazwie „work”, którą będzie wywoływał Michael, gdy będzie chciał wydać konkretne polecenie.
public class Assistant {
private String name;
public Assistant(String name) {
this.name = name;
}
public void work() {
System.out.println("Hold on Michael! I'm gonna rescue you");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Klasa „Main” to kierownik Dunder Mifflin – Michael Scott wydający ważne polecenia swoim pracownikom, który tworzy obiekt podając w konstruktorze konkretną osobę. Pierwszym poleceniem będzie przyjście na ratunek, dlatego też zostaje wywołana metoda na danym obiekcie. Wyświetla się poprawny komunikat – „Hold on Michael! I’m gonna rescue you!”. Kolejne polecenie to odebranie spodni z pralni. Zostaje wywołana po raz kolejny metoda „work”. Okazuje się jednak, że Dwight biegnie po raz kolejny na ratunek, a przecież miał inne zadanie. W takim przypadku, gdy nie chcemy za każdym razem dodawać nowych metod do klasy „Asystent”, a Michael chce wywoływać tylko i wyłącznie jedną i tą samą metodę możemy wykorzystać omawiany wzorzec.
public class MichaelScott {
public static void main(String[] args) {
//New order - Rescue me because I burned my foot
Assistant assistant = new Assistant("Dwight Schrute");
assistant.work();
//New order - Bring my jeans from dry-cleaner's
assistant.work();
}
}
Implementacja
Naszą implementację zaczynamy od stworzenia odpowiedniego interfejsu, który zawiera jedynie jedną metodę.
public interface Work {
void workHard();
}
Następnie tworzymy dwie klasy czyli nasze strategie, które implementują stworzony przez nas interfejs
public class BurnedFoot implements Work {
@Override
public void workHard() {
System.out.println("Hold on Michael! I'm gonna rescue you");
}
}
public class DryCleaners implements Work {
@Override
public void workHard() {
System.out.println("I will be right back with your Jeans");
}
}
Dokonujemy zmian w naszej klasie „Aystent”, dodając pole prywatne, które zwraca typ naszego Interfejsu przy udziale polimorfizmu oraz edytujemy naszą metodę „work”.
public class Assistant {
private String name;
private Work work;
public Assistant(String name) {
this.name = name;
}
public void work() {
this.work.workHard();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Work getWork() {
return work;
}
public void setWork(Work work) {
this.work = work;
}
}
Po dokonanych zmianach w kodzie, Michael ma teraz do wyboru konkretną strategie (setWork) w zależności od polecenia jakie chce wydać, po czym wywołuje dobrze sobie znaną metodę work i otrzymuje od Dwighta wiadomość adekwatną do danej sytuacji.
public class MichaelScott {
public static void main(String[] args) {
//New order - Rescue me because I burned my foot
Assistant assistant = new Assistant("Dwight Schrute");
assistant.setWork(new BurnedFoot());
assistant.work();
//New order - Bring my jeans from dry-cleaner's
assistant.setWork(new DryCleaners());
assistant.work();
}
}