Java programátor expert
Návrhové vzory Java (design patterns): Command
Dnes sa pozrieme na ďalší návrhový vzor Command (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 Command?
Návrhový vzor Command (príkaz) je vzor, ktorý zabalí požiadavky alebo operácie spolu s informáciami na ich vykonanie do samostatných objektov. Tieto informácie najčastejšie zahŕňajú názov metódy príslušného objektu spolu s parametrami metódy. So vzorom sú spojené vždy pojmy Client (klient) Command (príkaz), Receiver (príjemca), Invoker (vyvolávač). Klient rozhoduje o tom, aký príkaz a kedy vykonať. Aby príkaz vykonal, posunie príkazový objekt objektu vyvolávača. Vyvolávač nevie nič o konkrétnom objekte, pozná iba jeho rozhranie. Jeho úlohou je vykonať príkaz zavolaním metódy execute (vykonať) a prípadne zalogovať detaily vyvolanej operácie. Príjemca potom vykonáva prácu z príkazového objektu.
Aký problém návrhový vzor Command rieši?
Rieši problém oddelenia objektu, ktorý vyvoláva operáciu (vyvolávateľa) od objektu, ktorý túto operáciu vykonáva (prijímateľa), hlavným cieľom je vytvorenie flexibilného spojenia medzi objektami, ktoré spúšťajú požiadavky a tými, ktoré ich spracovávajú. Tieto objekty obsahujú všetky informácie potrebné na vykonanie danej operácie v pozadí a týmto spôsobom je možné pracovať s požiadavkami klienta podľa potreby s rozličnými parametrami. Požiadavky je možné ukladať do fronty na spracovanie, logovať ich, či dokonca implementovať aj reverzné operácie.
Príklad Command implementácie v Jave
Návrhový vzor je trochu komplikovanejší na pochopenie, preto som pripravil príklad, kde si jednotlivé role Client, Command, Receiver, Invoker podrobnejšie vysvetlíme. Napíšeme si jednoduchý program, ktorý bude cez príkazy ovládať baterku.
Prikaz.java
package designpatterns;
// Command rozhranie
public interface Prikaz {
void vykonat();
}
Rozhranie Prikaz definuje operáciu vykonat(), ktorú budú implementovať všetky konkrétne príkazy.
ZapnutSvetlo.java
package designpatterns;
// Konkrétny príkaz
public class ZapnutSvetlo implements Prikaz {
private Baterka baterka;
public ZapnutSvetlo(Baterka baterka) {
this.baterka = baterka;
}
@Override
public void vykonat() {
baterka.zapnut();
}
}
VypnutSvetlo.java
package designpatterns;
// Konkrétny príkaz
public class VypnutSvetlo implements Prikaz {
private Baterka baterka;
public VypnutSvetlo(Baterka baterka) {
this.baterka = baterka;
}
@Override
public void vykonat() {
baterka.vypnut();
}
}
Konkrétne príkazy ZapnutSvetlo a VypnutSvetlo implementujú rozhranie Prikaz a obsahujú referenciu na konkrétny objekt Baterka, ktorý bude vykonávať príslušnú operáciu.
Baterka.java
package designpatterns;
// Receiver
public class Baterka {
public void zapnut() {
System.out.println("Baterka svieti");
}
public void vypnut() {
System.out.println("Baterka je vypnuta");
}
}
Trieda Baterka predstavuje Receiver a obsahuje metódy, ktoré budú volané pri vykonávaní príkazov.
Vypinac.java
package designpatterns;
// Invoker
public class Vypinac {
private Prikaz prikaz;
public void nastavPrikaz(Prikaz prikaz) {
this.prikaz = prikaz;
}
public void stlacitTlacidlo() {
prikaz.vykonat();
}
}
Trieda Vypinac predstavuje Invoker a obsahuje referenciu na objekt typu Prikaz a má metódu stlacitTlacidlo(), ktorá volá operáciu vykonat() príslušného príkazu.
Main.java
import designpatterns.*;
// Klient
public class Main {
public static void main(String[] args) {
// Receiver
Baterka baterka = new Baterka();
// Command(s)
Prikaz zapnutSvetlo = new ZapnutSvetlo(baterka);
Prikaz vypnutSvetlo = new VypnutSvetlo(baterka);
// Invoker
Vypinac vypinac = new Vypinac();
// Nastavenie a spustenie príkazu.
vypinac.nastavPrikaz(zapnutSvetlo);
vypinac.stlacitTlacidlo();
// Nastavenie a spustenie iného príkazu.
vypinac.nastavPrikaz(vypnutSvetlo);
vypinac.stlacitTlacidlo();
}
}
Trieda Main predstavuje klienta. V metóde main vytvoríme príkazy na ovládanie baterky a prepojíme ich s prijímateľom, ktorý ich bude spracovávať. Vytvoríme aj objekt vyvolávateľa – vypínač, cez ktorého si klient nastaví konkrétny príkaz a ten sa vykoná po zavolaní metódy stacitTlacidlo(). Zjednodušene povedané, klient posiela príkazy vypínaču, ktorý ovláda baterku.
Výstup z tohto príkladu je:
Zhrnutie
Návrhový vzor Command sa pomerne často používa v prípadoch, keď sa potrebujeme zbaviť závislosti requestu (požiadavky) s priamou konkrétnou implementáciou. Ma široký priestor využitia v GUI, sieťovej komunikácií, databázových transakciách atď.
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 Command tu.
Ak si Java programátor a hľadáš prácu, pozri si naše benefity pre zamestnancov a reaguj na najnovšie pracovné ponuky.