Mediátorový vzor - Mediator pattern
v softwarové inženýrství, vzor mediátora definuje objekt, který zapouzdřuje jak sada objektů interaguje. Tento vzor je považován za a vzor chování kvůli způsobu, jakým může změnit chování programu.
V objektově orientovaném programování se programy často skládají z mnoha třídy. Obchodní logika a výpočet jsou rozděleny mezi tyto třídy. Jak se však do programu přidávají další třídy, zejména během údržba a / nebo refaktorování, problém sdělení mezi těmito třídami se může stát složitějším. Díky tomu je program těžší číst a udržovat. Dále může být obtížné změnit program, protože jakákoli změna může ovlivnit kód v několika dalších třídách.
S vzor mediátora, komunikace mezi objekty je zapouzdřena uvnitř a prostředník objekt. Objekty již nekomunikují přímo navzájem, ale místo toho komunikují prostřednictvím prostředníka. To snižuje závislosti mezi komunikujícími objekty, čímž se snižuje spojka.
Přehled
Zprostředkovatel[1] designový vzor je jedním z dvaceti tří známých designové vzory které popisují, jak řešit opakující se konstrukční problémy při navrhování flexibilního a opakovaně použitelného objektově orientovaného softwaru, tj. objektů, které se snadněji implementují, mění, testují a znovu používají.
Jaké problémy může návrhový vzor Mediatoru vyřešit?[2]
- Je třeba se vyhnout těsnému spojení mezi sadou interagujících objektů.
- Mělo by být možné nezávisle měnit interakci mezi sadou objektů.
Definování sady interagujících objektů přímým přístupem a vzájemnou aktualizací je nepružné, protože pevně spojuje objekty k sobě navzájem a znemožňuje změnit interakci nezávisle na (aniž by bylo nutné měnit) objekty. opakovaně použitelné a ztěžuje jejich testování.
Pevně spojené předměty je těžké je implementovat, změnit, otestovat a znovu použít, protože odkazují na mnoho různých objektů a vědí o nich.
Jaké řešení popisuje návrhový vzor Mediator?
- Definujte samostatný (zprostředkovatelský) objekt, který zapouzdřuje interakci mezi sadou objektů.
- Objekty delegují svou interakci na objekt mediátora namísto přímé interakce mezi sebou.
Objekty vzájemně interagují nepřímo prostřednictvím prostředníka, který řídí a koordinuje interakci.
To dělá objekty volně vázané. Odvolávají se pouze na svůj mediátorský objekt a vědí o něm a nemají o sobě žádné výslovné znalosti.
Viz také diagram tříd a sekvencí UML níže.
Definice
Podstatou vzoru Mediator je „definovat objekt, který zapouzdřuje způsob interakce sady objektů“. Podporuje volné spojení tím, že objekty výslovně neodkazuje na sebe, a umožňuje nezávisle měnit jejich interakci.[3][4] Třídy klientů mohou pomocí prostředníka odesílat zprávy dalším klientům a mohou přijímat zprávy od ostatních klientů prostřednictvím události ve třídě prostředníka.
Struktura
Třída a sekvenční diagram UML

Ve výše uvedeném UML třídní diagram, Kolega
a Kolega2
třídy neodkazují přímo na sebe (a aktualizují se). Místo toho odkazují na běžné Prostředník
rozhraní pro řízení a koordinaci interakce (zprostředkující()
), což je činí navzájem nezávislými, pokud jde o to, jak se interakce provádí Zprostředkovatel1
třída implementuje interakci mezi Kolega
a Kolega2
.
The UML sekvenční diagram ukazuje interakce za běhu. V tomto příkladu a Zprostředkovatel1
objekt zprostředkovává (řídí a koordinuje) interakci mezi Kolega
a Kolega2
předměty.
Za předpokladu, že Kolega
chce komunikovat Kolega2
(například k aktualizaci / synchronizaci jeho stavu), Kolega
hovory zprostředkovat (toto)
na Zprostředkovatel1
objekt, ze kterého získá změněná data Kolega
a provádí action2 ()
na Kolega2
.
Poté,Kolega2
hovory zprostředkovat (toto)
na Zprostředkovatel1
objekt, ze kterého získá změněná data Kolega2
a provádí akce1 ()
na Kolega
.
Diagram tříd

- Účastníci
Prostředník - definuje rozhraní pro komunikaci mezi Kolega předměty
ConcreteMediator - implementuje rozhraní Mediator a koordinuje komunikaci mezi Kolega předměty. Je si vědom všech Kolegové a jejich účely s ohledem na vzájemnou komunikaci.
Kolega - definuje rozhraní pro komunikaci s ostatními Kolegové přes jeho Prostředník
Konkrétní kolega - implementuje rozhraní kolegy a komunikuje s ostatními Kolegové přes jeho Prostředník
Příklad
C#
Mediator vzor zajišťuje, že komponenty jsou volně vázané, takže si navzájem výslovně nevolají, ale místo toho tak činí prostřednictvím volání zprostředkovateli. V následujícím příkladu Mediator zaregistruje všechny komponenty a poté zavolá jejich metody SetState.
rozhraní IComponent{ prázdnota SetState(objekt Stát);}třída Složka 1 : IComponent{ vnitřní prázdnota SetState(objekt Stát) { házet Nový NotImplementedException(); }}třída Složka2 : IComponent{ vnitřní prázdnota SetState(objekt Stát) { házet Nový NotImplementedException(); }}// Zprostředkovává běžné úkolytřída Prostředník{ vnitřní IComponent Složka 1 { dostat; soubor; } vnitřní IComponent Složka2 { dostat; soubor; } vnitřní prázdnota ChangeState(objekt Stát) { tento.Složka 1.SetState(Stát); tento.Složka2.SetState(Stát); }}
Chatovací místnost by mohla používat vzor Mediator nebo systém, kde každý z „klientů“ obdrží zprávu pokaždé, když některý z ostatních klientů provede nějakou akci (v chatovacích místnostech to bude, když každá osoba pošle zprávu). Ve skutečnosti by použití vzoru Mediator pro chatovací místnost bylo praktické pouze při použití s vzdálená komunikace. Použití surových zásuvek by neumožňovalo delegát zpětná volání (lidé se přihlásili k odběru události MessageReceived třídy Mediator).
veřejnost delegát prázdnota MessageReceivedEventHandler(tětiva zpráva, tětiva odesílatel);veřejnost třída Prostředník{ veřejnost událost MessageReceivedEventHandler Zpráva přijata; veřejnost prázdnota Poslat(tětiva zpráva, tětiva odesílatel) { -li (Zpráva přijata != nula) { Řídicí panel.WriteLine(„Odesílání„ {0} “z {1}, zpráva, odesílatel); Zpráva přijata(zpráva, odesílatel); } }}veřejnost třída Osoba{ soukromé Prostředník _prostředník; veřejnost tětiva název { dostat; soubor; } veřejnost Osoba(Prostředník prostředník, tětiva název) { název = název; _prostředník = prostředník; _prostředník.Zpráva přijata += Nový MessageReceivedEventHandler(Dostávat); } soukromé prázdnota Dostávat(tětiva zpráva, tětiva odesílatel) { -li (odesílatel != název) Řídicí panel.WriteLine(„{0} přijal„ {1} “od {2}“, název, zpráva, odesílatel); } veřejnost prázdnota Poslat(tětiva zpráva) { _prostředník.Poslat(zpráva, název); }}
Jáva
V následujícím příkladu a Prostředník
objekt řídí hodnoty několika Úložný prostor
objekty, nutí uživatelský kód k přístupu k uloženým hodnotám prostřednictvím mediátora. Když chce objekt úložiště emitovat událost označující, že se jeho hodnota změnila, vrátí se také zpět k objektu mediátoru (prostřednictvím metody notifyObservers
), který řídí seznam pozorovatelů (implementovaný pomocí vzor pozorovatele ).
import java.util.HashMap;import java.util. Volitelné;import java.util.concurrent.CopyOnWriteArrayList;import java.util.function.Consumer;třída Úložný prostor<T> { T hodnota; T getValue() { vrátit se hodnota; } prázdnota setValue(Prostředník<T> prostředník, Tětiva storageName, T hodnota) { tento.hodnota = hodnota; prostředník.notifyObservers(storageName); }}třída Prostředník<T> { soukromé finále HashMap<Tětiva, Úložný prostor<T>> storageMap = Nový HashMap<>(); soukromé finále CopyOnWriteArrayList<Spotřebitel<Tětiva>> pozorovatelé = Nový CopyOnWriteArrayList<>(); veřejnost prázdnota setValue(Tětiva storageName, T hodnota) { Úložný prostor úložný prostor = storageMap.computeIfAbsent(storageName, název -> Nový Úložný prostor<>()); úložný prostor.setValue(tento, storageName, hodnota); } veřejnost Volitelný<T> getValue(Tětiva storageName) { vrátit se Volitelný.ofNullable(storageMap.dostat(storageName)).mapa(Úložný prostor::getValue); } veřejnost prázdnota addObserver(Tětiva storageName, Spustitelný pozorovatel) { pozorovatelé.přidat(název události -> { -li (název události.rovná se(storageName)) { pozorovatel.běh(); } }); } prázdnota notifyObservers(Tětiva název události) { pozorovatelé.pro každého(pozorovatel -> pozorovatel.akceptovat(název události)); }}veřejnost třída Mediator Demo { veřejnost statický prázdnota hlavní(Tětiva[] args) { Prostředník<Celé číslo> prostředník = Nový Prostředník<>(); prostředník.setValue("bob", 20); prostředník.setValue("alice", 24); prostředník.getValue("alice").ifPresent(stáří -> Systém.ven.tisk("age for alice:" + stáří)); prostředník.addObserver("bob", () -> { Systém.ven.tisk(„new age for bob:“ + prostředník.getValue("bob").neboElseThrow(RuntimeException::Nový)); }); prostředník.setValue("bob", 21); }}
Viz také
- Zprostředkování dat
- Designové vzory, kniha, která dala vzniknout studiu návrhových vzorů v informatice
- Návrhový vzor (informatika), standardní řešení běžných problémů při návrhu softwaru
Reference
- ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Návrhové vzory: Prvky opakovaně použitelného objektově orientovaného softwaru. Addison Wesley. str.273ff. ISBN 0-201-63361-2.CS1 maint: více jmen: seznam autorů (odkaz)
- ^ Franke, Günther. „Návrhový vzor mediátoru - problém, řešení a použitelnost“. w3sDesign. Citováno 2017-08-12.
- ^ Gamma, Erichu; Helm, Richard; Johnson, Ralph; Vlissides, Johne (1994). Designové vzory. Addison-Wesley. ISBN 0-201-63361-2.
- ^ „Návrhový vzor mediátora“. Tvorba zdrojů.
- ^ Franke, Günther. „Návrhový vzor Mediator - struktura a spolupráce“. w3sDesign. Citováno 2017-08-12.
externí odkazy
- Kaiser, Bodo (2012-09-21). „Doporučuje se použití vzoru zprostředkovatele?“. Přetečení zásobníku.