Java programátor expert
Návrhové vzory Java (design patterns): Chain of Reponsibility
Dnes sa pozrieme na prvý návrhový vzor Chain of Responsibility (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 Chain of Responsibility?
Návrhový vzor Chain of Responsibility (reťaz zodpovednosti) je vzor, ktorý umožňuje viacerým objektom spracovávať požiadavky bez nutnosti, aby objekt vedel, kto je jeho nasledovník v reťazi. Každý objekt v reťazi má možnosť spracovať požiadavku, ale ak nevie, ako ju spracovať, prenáša ju na nasledujúci objekt v reťazi.
Aký problém návrhový vzor Chain of Responsibility rieši?
Rieši problém spracovania požiadaviek v reťazi a to tak, že namiesto toho, aby bola požiadavka poslaná na konkrétny objekt, žiadosť putuje reťazou objektov, kde každý objekt v reťazi môže byť zodpovedný za jej spracovanie, ale ak ju nespracuje, prenesie ju na ďalší objekt v reťazi. Cieľom je umožniť viacerým objektom spracovať požiadavku bez nutnosti presne určiť, ktorý objekt ju bude spracovávať a tak dosiahnuť zníženie vzájomnej závislosti medzi odosielateľom a prijímateľom požiadavky.
Príklad Chain of Responsibility implementácie v Jave
Teraz si napíšeme program, ktorý bude simulovať schvaľovanie požiadaviek zamestnanca vo firme s použitím návrhového vzoru Chain of Responsibility. Cieľom tohto vzoru je umožniť viacerým objektom spracovať požiadavku bez toho, aby sme presne vedeli, ktorý objekt ju spracuje. Objekty sú zoradené do reťaze a každý objekt v reťazi rozhoduje, či vie spracovať danú požiadavku alebo ju prenesie na ďalší objekt v reťazi.
V tomto programe existujú tri typy zamestnancov – Zamestnanec, Veduci a Riaditel, každý z nich implementuje abstraktnú triedu SchvalovatelPoziadavky, ktorá obsahuje spoločnú funkcionalitu pre všetkých zamestnancov.
SchvalovatelPoziadavky.java
package designpatterns;
public abstract class SchvalovatelPoziadavky {
String meno;
SchvalovatelPoziadavky dalsiSchvalovatel;
private SchvalovatelPoziadavky(){
}
public SchvalovatelPoziadavky(String meno){
this.meno = meno;
}
public abstract void nastavitDalsiehoSchvalovatela(SchvalovatelPoziadavky dalsiSchvalovatel);
public void posuditPoziadavku(String poziadavka)
{
if(this.dalsiSchvalovatel != null)
this.dalsiSchvalovatel.posuditPoziadavku(poziadavka);
else
System.out.println(poziadavka + " - poziadavka bola zamietnuta!");
}
}
Abstraktná trieda SchvalovatelPoziadavky definuje spoločné metódy a obsahuje referenciu na ďalšieho schvaľovateľa v reťazi.
Zamestnanec.java
package designpatterns;
public class Zamestnanec extends SchvalovatelPoziadavky {
public Zamestnanec() {
super("zamestnanec");
}
@Override
public void nastavitDalsiehoSchvalovatela(SchvalovatelPoziadavky dalsiSchvalovatel) {
this.dalsiSchvalovatel = dalsiSchvalovatel;
}
@Override
public void posuditPoziadavku(String poziadavka) {
if(poziadavka == "NAVSTEVA_LEKARA") {
System.out.println(poziadavka + " - " + meno + " schvalil poziadavku");
}
else {
super.posuditPoziadavku(poziadavka);
}
}
}
Veduci.java
package designpatterns;
public class Veduci extends SchvalovatelPoziadavky {
public Veduci() {
super("veduci");
}
@Override
public void nastavitDalsiehoSchvalovatela(SchvalovatelPoziadavky dalsiSchvalovatel) {
this.dalsiSchvalovatel = dalsiSchvalovatel;
}
@Override
public void posuditPoziadavku(String poziadavka) {
if(poziadavka == "DOVOLENKA") {
System.out.println(poziadavka + " - " + meno + " schvalil poziadavku");
}
else {
super.posuditPoziadavku(poziadavka);
}
}
}
Riaditel.java
package designpatterns;
public class Riaditel extends SchvalovatelPoziadavky {
public Riaditel() {
super("riaditel");
}
@Override
public void nastavitDalsiehoSchvalovatela(SchvalovatelPoziadavky dalsiSchvalovatel) {
this.dalsiSchvalovatel = dalsiSchvalovatel;
}
@Override
public void posuditPoziadavku(String poziadavka) {
if(poziadavka == "ZVYSENIE_PLATU") {
System.out.println(poziadavka + " - " + meno + " schvalil poziadavku");
}
else {
super.posuditPoziadavku(poziadavka);
}
}
}
Zamestnanec, Veduci, Riaditel sú konkrétne triedy reprezentujúce jednotlivých zamestnancov. Každý z nich môže schvaľovať určité typy požiadaviek, ale ak na niektoré nie je oprávnený, prenesie ich na ďalšieho schvaľovateľa v reťazi.
Main.java
import designpatterns.Riaditel;
import designpatterns.SchvalovatelPoziadavky;
import designpatterns.Veduci;
import designpatterns.Zamestnanec;
public class Main {
public static void main(String[] args) {
// Clanky retaze
SchvalovatelPoziadavky zamestnanec = new Zamestnanec();
SchvalovatelPoziadavky veduci = new Veduci();
SchvalovatelPoziadavky riaditel = new Riaditel();
// Vytvorenie retaze zodpovednosti
zamestnanec.nastavitDalsiehoSchvalovatela(veduci);
veduci.nastavitDalsiehoSchvalovatela(riaditel);
// Posudenie poziadaviek
zamestnanec.posuditPoziadavku("NAVSTEVA_LEKARA");
zamestnanec.posuditPoziadavku("DOVOLENKA");
zamestnanec.posuditPoziadavku("ZVYSENIE_PLATU");
zamestnanec.posuditPoziadavku("FIREMNE_AUTO");
}
}
V metóde main vytvárame reťaz zodpovedností, vytvárame hierarchiu jednotlivých zamestnancov a potom posudzujeme rôzne požiadavky. Každý zamestnanec sa pokúsi schváliť požiadavku. Ak ju nemôže schváliť, deleguje ju na ďalšieho schvaľovateľa v reťazi.
Zhrnutie
Návrhový vzor Chain of Responsibility sa používa v softvérovom dizajne, keď potrebujeme dosiahnuť flexibilný spôsob spracovania požiadaviek, pričom nechceme vytvárať pevnú väzbu medzi odosielateľom a spracovateľom požiadavky a odovzdávame ich reťazi objektov na spracovanie.
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 Chain of Responsibility 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.