Wzorzec State jest wzorcem operacyjnym, który posiada wiele implementacji i może się przełączać pomiędzy nimi podczas działania programu. Zmiana może być spowodowana interakcją użytkownika lub też automatycznie przez klasę kliencką jako odpowiedź na wykonaną akcję. Korzystanie z wzorca eliminuje wiele instrukcji warunkowych z kodu, które uzależnieją wykonane operacji od odpowiedniego warunku. W state takie warunki przeniesione są do oddzielnych klas.
Spójrzmy na kod:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
public class BadStateKlas { private boolean warunek = true; public static void main(String[] args) { BadStateKlas bad = new BadStateKlas(); } public BadStateKlas() { metoda1(); metoda2(); } private void metoda1() { //kod wykonujemy gdy wartość pola 'warunek' jest = true if (warunek) { System.out.println("Wykonuję metodę 1"); } else { System.out.println("Nie wykonuję metody 1"); } } private void metoda2() { // kod wykonujemy gdy wartość pola 'warunek' jest = false if (!warunek) { System.out.println("Wykonuję metodę 2"); } else { System.out.println("Nie wykonuję metody 2"); } } } |
Kod wykonywany w metodach 1 i 2 jest zależny od wartości pola ‚warunek’. A co jeżeli będę trzy możliwości? Pole warunek trzeba będzie zmienić z boolean na int lub Enum, a listy ‚ifów’ będą coraz dłuższe. Zamiast tego ustawimy pole stan dla klasy, a kod zależny od tego pola umieścimy w zewnętrznych klasach.
Interfejs:
1 2 3 4 5 6 |
public interface Warunek { public void metoda1(); public void metoda2(); } |
Poszczególne stany:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Warunek1 implements Warunek{ public void metoda1() { System.out.println("Wykonuję metodę 1"); } public void metoda2() { System.out.println("Nie wykonuję metody 2"); } } public class Warunek2 implements Warunek{ public void metoda1() { System.out.println("Nie wykonuję metody 1"); } public void metoda2() { System.out.println("Wykonuję metodę 2"); } } |
Klasa klienta:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class GoodState { private Warunek warunek; public GoodState(Warunek warunek) { this.warunek = warunek; warunek.metoda1(); warunek.metoda2(); } public void setWarunek(Warunek warunek) { this.warunek = warunek; } public static void main(String[] args) { GoodState state = new GoodState(new Warunek1()); } } |
Diagram wzorca: