Uzorak posrednika u Javi

1. Pregled

U ovom ćemo članku pogledati obrazac medijatora, jedan od obrazaca ponašanja GoF-a. Opisat ćemo njegovu svrhu i objasniti kada bismo je trebali koristiti.

Kao i obično, pružit ćemo i jednostavan primjer koda.

2. Uzorak posrednika

U objektno orijentiranom programiranju uvijek bismo trebali pokušati dizajnirajte sustav na takav način da su komponente labavo povezane i mogu se ponovno koristiti. Ovaj pristup olakšava održavanje i testiranje našeg koda.

Međutim, u stvarnom životu često se moramo nositi sa složenim nizom ovisnih objekata. Tada može dobro doći obrazac medijatora.

Namjera Obrasca Posrednika je smanjiti složenost i ovisnosti između tijesno povezanih objekata koji izravno komuniciraju jedni s drugima. To se postiže stvaranjem objekta posrednika koji se brine o interakciji između ovisnih objekata. Slijedom toga, sva komunikacija prolazi posrednika.

Ovo promiče labavo spajanje, jer skup komponenata koji rade zajedno više ne mora izravno komunicirati. Umjesto toga, oni se odnose samo na jedan objekt posrednika. Na taj je način također lakše ponovno koristiti ove objekte u drugim dijelovima sustava.

3. UML dijagram uzorka medijatora

Pogledajmo sada obrazac vizualno:

U gornjem UML dijagramu možemo identificirati sljedeće sudionike:

  • Posrednik definira sučelje Suradnik predmeti koriste za komunikaciju
  • Suradnik definira apstraktnu klasu koja sadrži jednu referencu na Posrednik
  • ConcreteMediator enkapsulira logiku interakcije između Suradnik predmeta
  • BetonskaKolega1 i ConcreteColleague2 komunicirati samo putem Posrednik

Kao što vidimo, Suradnik predmeti se međusobno ne odnose izravno. Umjesto toga, svu komunikaciju provodi Posrednik.

Slijedom toga, BetonskaKolega1 i ConcreteColleague2 može se lakše upotrijebiti.

Također, u slučaju da trebamo promijeniti način Suradnik predmeti rade zajedno, moramo samo izmijeniti i dopuniti ConcreteMediator logika. Ili možemo stvoriti novu implementaciju Posrednik.

4. Implementacija Jave

Sad kad imamo jasnu ideju o teoriji, pogledajmo primjer za bolje razumijevanje koncepta u praksi.

4.1. Primjer scenarija

Zamislite da gradimo jednostavan sustav hlađenja koji se sastoji od ventilatora, napajanja i gumba. Pritiskom na tipku ventilator će se uključiti ili isključiti. Prije nego što uključimo ventilator, moramo uključiti napajanje. Slično tome, napajanje moramo isključiti odmah nakon isključivanja ventilatora.

Pogledajmo sada primjer implementacije:

gumb javne klase {privatni obožavatelj obožavatelja; // konstruktor, geteri i postavljači public void press () {if (fan.isOn ()) {fan.turnOff (); } else {fan.turnOn (); }}}
ventilator javne klase {gumb privatnog gumba; privatni PowerSupplier powerSupplier; private boolean isOn = false; // konstruktor, getteri i postavljači public void turnOn () {powerSupplier.turnOn (); isOn = točno; } public void turnOff () {isOn = false; powerSupplier.turnOff (); }}
javna klasa PowerSupplier {public void turnOn () {// implementacija} public void turnOff () {// implementacija}}

Dalje, testirajmo funkcionalnost:

@Test javna praznina givenTurnedOffFan_whenPressingButtonTwice_fanShouldTurnOnAndOff () {assertFalse (fan.isOn ()); button.press (); assertTrue (fan.isOn ()); button.press (); assertFalse (fan.isOn ()); }

Čini se da sve funkcionira u redu. Ali primijetite kako Gumb, ventilator, i PowerSupplier razredi su usko povezani. The Dugme djeluje izravno na Ventilator i Ventilator komunicira s obojicom Dugme i PowerSupplier.

Bilo bi teško ponovno koristiti Dugme razred u ostalim modulima. Također, ako trebamo dodati drugo napajanje u naš sustav, tada bismo morali izmijeniti Ventilator logika klase.

4.2. Dodavanje uzorka medijatora

Sada, implementirajmo Mediator Pattern da smanjimo ovisnosti između naših klasa i učinimo kod višekratnim.

Prvo, predstavimo Posrednik razred:

posrednik javne klase {gumb privatnog gumba; privatni ventilator obožavatelja; privatni PowerSupplier powerSupplier; // konstruktor, geteri i postavljači public void press () {if (fan.isOn ()) {fan.turnOff (); } else {fan.turnOn (); }} javni void start () {powerSupplier.turnOn (); } javna void stop () {powerSupplier.turnOff (); }}

Dalje, izmijenimo preostale klase:

gumb javne klase {privatni posrednik posrednik; // konstruktor, geteri i postavljači public void press () {mediator.press (); }}
obožavatelj javne klase {privatni posrednik posrednik; private boolean isOn = false; // konstruktor, getteri i postavljači public void turnOn () {mediator.start (); isOn = istina; } public void turnOff () {isOn = false; posrednik.stop (); }}

Ponovno, testirajmo funkcionalnost:

@Test javna praznina givenTurnedOffFan_whenPressingButtonTwice_fanShouldTurnOnAndOff () {assertFalse (fan.isOn ()); button.press (); assertTrue (fan.isOn ()); button.press (); assertFalse (fan.isOn ()); }

Naš sustav hlađenja radi kako se očekivalo.

Sad kad smo implementirali obrazac medijatora, nijedan od njih Dugme, Ventilator, ili PowerSupplier razredi izravno komuniciraju. Imaju samo jednu referencu na Posrednik.

Ako u budućnosti trebamo dodati drugo napajanje, sve što moramo učiniti je ažurirati Posrednikova logika; Dugme i Ventilator satovi ostaju netaknuti.

Ovaj primjer pokazuje kako lako možemo razdvojiti ovisne objekte i olakšati održavanje sustava.

5. Kada koristiti obrazac medijatora

Uzorak medijatora dobar je izbor ako moramo riješiti niz predmeta koji su čvrsto povezani i teško ih je održavati. Na taj način možemo smanjiti ovisnosti između objekata i smanjiti ukupnu složenost.

Uz to, korištenjem objekta posrednika, izvlačimo komunikacijsku logiku u jednu komponentu, stoga slijedimo Princip jedinstvene odgovornosti. Nadalje, možemo uvesti nove posrednike bez potrebe za promjenom preostalih dijelova sustava. Stoga slijedimo načelo otvoreno-zatvoreno.

Međutim, ponekad možemo imati previše čvrsto povezanih predmeta zbog neispravnog dizajna sustava. Ako je to slučaj, ne bismo trebali primjenjivati ​​obrazac medijatora. Umjesto toga, trebali bismo napraviti jedan korak unatrag i preispitati način na koji smo modelirali svoje predmete.

Kao i kod svih ostalih obrazaca, moramo razmotriti naš specifični slučaj upotrebe prije nego što slijepo primijenimo obrazac medijatora.

6. Zaključak

U ovom smo članku saznali o obrascu Posrednika. Objasnili smo koji problem ovaj obrazac rješava i kada bismo ga zapravo trebali razmotriti. Također smo implementirali jednostavan primjer uzorka dizajna.

Kao i uvijek, cjeloviti uzorci koda dostupni su na GitHubu.