Návrhové vzory Java (design patterns): State

Dnes sa pozrieme na ďalší návrhový vzor State (java design patterns) z kategórie vzorov správania (behavioral patterns). Návrhové vzory v tejto kategórii sa zaoberajú komunikáciou (interaction) medzi objektami a ich zodpovednosťou (responsibility).

Čo je návrhový vzor State?

State je návrhový vzor, ktorý umožňuje objektu zmeniť svoje správanie, keď sa zmení jeho vnútorný stav. Vo vzore vytvárame objekty, ktoré predstavujú jednotlivé stavy a kontextový objekt, ktorého správanie sa mení v závislosti od stavu objektu.

Pre lepšie pochopenie predstavme si jednoduchý automat na predaj lístkov. Jeho správanie sa mení v závislosti od toho, v akej fáze nákupného procesu (konkrétneho stavu) sa nachádza (napr. výber lístka, platba, potvrdenie). Implementácia tohto automatizovaného procesu pomocou návrhového vzoru State by umožnila urobilo kód prehľadnejším, pretože by biznis logiku každej fázy rozdelila do samostatných stavov.

Aký problém návrhový vzor State rieši?

Vzor State (Stav) rieši problém, keď sa objekt správa rôzne v závislosti od svojho aktuálneho stavu. Umožňuje definovať rôzne stavy a prechody medzi nimi, čím udržuje stavovú logiku oddelenú od hlavnej logiky objektu. Tento koncept je podobný konečným automatom (FSM – Finite State Machine). Správanie každého stavu je definované nezávislé na ostatných stavoch a pridávanie nových stavov by nemalo ovplyvniť správanie existujúcich stavov.

Príklad State implementácie v Jave

Praktické použitie návrhového vzoru State si ukážeme na príklade semaforu so stavmi červená, oranžová a zelená, ktorý riadi cestnú premávku.

StavSemaforu.java

package designpatterns;

public interface StavSemaforu {
    void vykonat();
}

StavSemaforu je rozhranie, ktoré definuje metódu vykonat(). Každý stav semaforu (červená, oranžová, zelená) implementuje toto rozhranie a poskytuje vlastnú implementáciu vykonat().

Cervena.java, Oranzova.java, Zelena.java

package designpatterns;

public class Cervena implements StavSemaforu {
    @Override
    public void vykonat() {
        System.out.println("Svetlo na semafore sa preplo na červenú - premávka sa zastavila.");
    }
}

public class Oranzova implements StavSemaforu {
    @Override
    public void vykonat() {
        System.out.println("Svetlo na semafore sa preplo na oranžovú - čaká sa na zmenu.");
    }
}

public class Zelena implements StavSemaforu {
    @Override
    public void vykonat() {
        System.out.println("Svetlo na semafore sa preplo na zelenú - premávka sa rozbieha.");
    }
}

Cervena, Oranzova a Zelena sú implementácie rozhrania StavSemaforu. Každá z týchto tried reprezentuje jeden konkrétny stav semaforu a poskytuje vlastnú implementáciu pre vykonat().

Semafor.java

package designpatterns;

// Kontext, ktory prepina stavy
public class Semafor {
    private StavSemaforu stav;

    public Semafor() {
        this.stav = new Oranzova();
    }

    public void prepnut(StavSemaforu novyStav) {
        this.stav = novyStav;
    }

    public void vykonat() {
        stav.vykonat();
    }
}

Semafor je trieda, ktorá predstavuje kontext, kde sa stavy semaforu menia. V tomto prípade sa Semafor inicializuje na stav Oranzova. Má metódu prepnut(), ktorá mení aktuálny stav semaforu na zadaný nový stav. Tiež má metódu vykonat(), ktorá vykonáva aktuálny stav semaforu.

Main.java

import designpatterns.Cervena;
import designpatterns.Oranzova;
import designpatterns.Semafor;
import designpatterns.Zelena;

public class Main {
    public static void main(String[] args) {
        // Semafor je na zaciatku inicializovany na stav oranzova.
        Semafor semafor = new Semafor();
        semafor.vykonat();
        semafor.prepnut(new Cervena());
        semafor.vykonat();
        semafor.prepnut(new Oranzova());
        semafor.vykonat();
        semafor.prepnut(new Zelena());
        semafor.vykonat();
    }
}

V triede Main simulujeme prevádzku dopravného semaforu. Vytvárame inštanciu semaforu, ktorý je na začiatku v stave oranžová. Potom meníme stav semaforu pomocou metódy prepnut() a následne voláme metódu vykonat(), ktorá spracuje biznis logiku definovanú pre daný stav.

Výstup z tohto príkladu je:

Výstup príkladu pre návrhové vzory Java: State (design pattern)

Zhrnutie

Vzor State je vhodné použiť v prípade, ak máme pre objekt definované konečné množstvo stavov, ktorými môže prechádzať a potrebujeme pri zmene jeho vnútorného stavu vykonať nejakú akciu.

Pripravili sme pre teba súbory so spomínaným príkladom vo forme kódu, ktorý si môžeš spustiť priamo v Jave. Stiahni si kód Java State tu.

Ak si Java programátor a hľadáš prácu, pozri si naše benefity pre zamestnancov a reaguj na najnovšie ponuky práce.

O autorovi

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Daj nám o sebe vedieť