Vzor sprostredkovateľa v Jave

1. Prehľad

V tomto článku sa pozrieme na Mediator Pattern, jeden zo vzorcov správania GoF. Popíšeme jeho účel a vysvetlíme, kedy by sme ho mali použiť.

Ako obvykle poskytneme aj jednoduchý príklad kódu.

2. Vzor mediátora

V objektovo orientovanom programovaní by sme sa mali vždy snažiť navrhnúť systém tak, aby boli komponenty voľne spojené a opakovane použiteľné. Tento prístup uľahčuje údržbu a testovanie nášho kódu.

V skutočnom živote však často musíme narábať so zložitou sadou závislých objektov. Vtedy sa vám môže hodiť vzor sprostredkovateľa.

Účelom vzoru mediátora je znížiť zložitosť a závislosti medzi pevne spojenými objektmi, ktoré navzájom priamo komunikujú.. To sa dosiahne vytvorením objektu sprostredkovateľa, ktorý sa postará o interakciu medzi závislými objektmi. Následne všetka komunikácia prechádza sprostredkovateľom.

Toto podporuje voľné spojenie, pretože sada komponentov, ktoré spolupracujú, už nemusia priamo interagovať. Namiesto toho odkazujú iba na jeden objekt sprostredkovateľa. Týmto spôsobom je tiež jednoduchšie znova použiť tieto objekty v iných častiach systému.

3. Diagram UML sprostredkovateľského vzoru

Pozrime sa teraz na vzor vizuálne:

Vo vyššie uvedenom diagrame UML môžeme identifikovať týchto účastníkov:

  • Sprostredkovateľ definuje rozhranie Kolega objekty používajú na komunikáciu
  • Kolega definuje abstraktnú triedu obsahujúcu jediný odkaz na Sprostredkovateľ
  • ConcreteMediator zapuzdruje logiku interakcie medzi Kolega predmety
  • ConcreteColleague1 a ConcreteColleague2 komunikovať iba prostredníctvom Sprostredkovateľ

Ako vidíme, Kolega objekty sa na seba priamo nevzťahujú. Namiesto toho všetku komunikáciu vykonáva Sprostredkovateľ.

V dôsledku toho ConcreteColleague1 a ConcreteColleague2 sa dajú ľahšie znovu použiť.

Tiež pre prípad, že by sme potrebovali zmeniť spôsob Kolega objekty spolupracujú, musíme iba zmeniť a doplniť ConcreteMediator logika. Alebo môžeme vytvoriť novú implementáciu Sprostredkovateľ.

4. Implementácia Java

Teraz, keď máme jasnú predstavu o teórii, pozrime sa na príklad, aby sme lepšie pochopili tento koncept v praxi.

4.1. Príklad scenára

Predstavte si, že staviame jednoduchý chladiaci systém, ktorý sa skladá z ventilátora, napájacieho zdroja a tlačidla. Stlačením tlačidla sa ventilátor zapne alebo vypne. Predtým, ako zapneme ventilátor, je potrebné zapnúť napájanie. Podobne musíme vypnúť napájanie hneď po vypnutí ventilátora.

Poďme sa teraz pozrieť na príklad implementácie:

public class Button {private Fan fan; // konštruktor, getri a nastavovatelia public void press () {if (fan.isOn ()) {fan.turnOff (); } else {fan.turnOn (); }}}
public class Fan {private Button button; súkromný PowerSupplier powerSupplier; private boolean isOn = false; // konštruktor, getri a nastavovatelia public void turnOn () {powerSupplier.turnOn (); isOn = true; } public void turnOff () {isOn = false; powerSupplier.turnOff (); }}
verejná trieda PowerSupplier {public void turnOn () {// implementácia} public void turnOff () {// implementácia}}

Ďalej otestujeme funkčnosť:

@Test public void givenTurnedOffFan_whenPressingButtonTwice_fanShouldTurnOnAndOff () {assertFalse (fan.isOn ()); button.press (); assertTrue (fan.isOn ()); button.press (); assertFalse (fan.isOn ()); }

Zdá sa, že všetko funguje dobre. Všimnite si však ako Gombík, ventilátor, a PowerSupplier triedy sú pevne spojené. The Tlačidlo pôsobí priamo na internete Ventilátor a Ventilátor interaguje s oboma Tlačidlo a PowerSupplier.

Bolo by ťažké znovu použiť Tlačidlo triedy v ďalších moduloch. Tiež, ak potrebujeme do nášho systému pridať druhý zdroj napájania, budeme musieť upraviť Ventilátor logika triedy.

4.2. Pridanie vzoru sprostredkovateľa

Teraz poďme implementovať vzor sprostredkovateľa, aby sme znížili závislosti medzi našimi triedami a zaistili, že sa kód stane znovu použiteľným.

Najprv si predstavíme Sprostredkovateľ trieda:

verejná trieda Mediator {tlačidlo súkromného tlačidla; súkromný ventilátor; súkromný PowerSupplier powerSupplier; // konštruktor, getri a nastavovatelia public void press () {if (fan.isOn ()) {fan.turnOff (); } else {fan.turnOn (); }} public void start () {powerSupplier.turnOn (); } public void stop () {powerSupplier.turnOff (); }}

Ďalej upravíme zostávajúce triedy:

verejná trieda Tlačidlo {súkromný mediátor mediátor; // konštruktor, getri a nastavovatelia public void press () {mediator.press (); }}
public class Fan {private Mediator mediátor; private boolean isOn = false; // konštruktor, getri a nastavovatelia public void turnOn () {mediator.start (); isOn = true; } public void turnOff () {isOn = false; mediator.stop (); }}

Opäť otestujme funkčnosť:

@Test public void givenTurnedOffFan_whenPressingButtonTwice_fanShouldTurnOnAndOff () {assertFalse (fan.isOn ()); button.press (); assertTrue (fan.isOn ()); button.press (); assertFalse (fan.isOn ()); }

Náš chladiaci systém funguje podľa očakávaní.

Teraz, keď sme implementovali vzor mediátora, žiadny z nich Tlačidlo, Ventilátoralebo PowerSupplier triedy komunikujú priamo. Majú iba jediný odkaz na Sprostredkovateľ.

Ak v budúcnosti budeme musieť pridať druhý zdroj napájania, musíme iba aktualizovať Mediátor logika; Tlačidlo a Ventilátor triedy zostávajú nedotknuté.

Tento príklad ukazuje, ako ľahko môžeme oddeliť závislé objekty a uľahčiť údržbu nášho systému.

5. Kedy použiť vzor sprostredkovateľa

Mediátorový vzor je dobrou voľbou, ak sa musíme zaoberať súborom objektov, ktoré sú pevne spojené a ťažko sa udržiavajú. Týmto spôsobom môžeme znížiť závislosti medzi objektmi a znížiť celkovú zložitosť.

Pomocou objektu sprostredkovateľa navyše extrahujeme komunikačnú logiku na jednu súčasť, preto sa riadime princípom jednej zodpovednosti. Ďalej môžeme predstaviť nových sprostredkovateľov bez potreby meniť zvyšné časti systému. Preto sa riadime princípom otvoreného a uzavretého.

Niekedy však môžeme mať príliš veľa pevne prepojených objektov kvôli chybnej konštrukcii systému. V takom prípade by sme nemali použiť vzor mediátora. Namiesto toho by sme sa mali vrátiť o krok späť a prehodnotiť spôsob, akým sme vymodelovali naše triedy.

Rovnako ako u všetkých ostatných vzorov, pred slepou implementáciou modelu mediátora musíme zvážiť náš konkrétny prípad použitia.

6. Záver

V tomto článku sme sa dozvedeli o vzore sprostredkovateľa. Vysvetlili sme, aký problém tento vzor rieši a kedy by sme mali skutočne uvažovať o jeho použití. Implementovali sme tiež jednoduchý príklad návrhového vzoru.

Kompletné ukážky kódu sú ako vždy k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found