Mediator (designmønster)
Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den
version , der blev gennemgået den 16. marts 2014; checks kræver
22 redigeringer .
Mediator er et adfærdsdesignmønster , der sikrer interaktionen mellem mange objekter, samtidig med at de danner et svagt led og eliminerer behovet for, at objekter eksplicit henviser til hinanden.
Problem
Sørg for samspillet mellem mange objekter, mens du danner løs kobling og eliminerer behovet for, at objekter eksplicit henviser til hinanden.
Løsning
Opret et objekt, der indkapsler , hvor mange objekter der interagerer.
Fordele
Forbindelsen mellem "Kolleger" er elimineret, ledelsen er centraliseret.
Struktur
- Mægler - "mellemmand"
- ConcreteMediator - "Betonformidler"
- Kollegaklasser - "kollegaer"
Beskrivelse
"Mediator" definerer en grænseflade til udveksling af information med "Colleagues"-objekter, "Specific mediator" koordinerer handlingerne for "Colleagues"-objekter. Hver klasse "kollegaer" kender sit "mediator"-objekt, alle "kollegaer" udveksler kun information med mægleren, i dens fravær ville de skulle udveksle information direkte. "Kolleger" sender anmodninger til formidleren og modtager anmodninger fra ham. Mægleren implementerer samarbejdsadfærd ved at videresende hver anmodning til en eller flere kolleger.
Eksempler
PHP5 eksempel
Kildekode i
PHP5
<?php
abstrakt klasse Mediator
{
abstrakt offentlig funktion send ( $meddelelse , kollega $kollega );
}
abstrakt klasse Kollega
{
beskyttet $mediator ;
public function __construct ( mediator $mediator )
{
$this -> mediator = $mediator ;
}
public function send ( $message )
{
$this -> mediator -> send ( $message , $this );
}
/**
* Behandlingen af den modtagne besked implementeres af hver * * konkret
efterfølger
* @param string besked den modtagne besked
*/
abstrakt offentlig funktion notify ( $message );
}
klasse ConcreteMediator udvider Mediator
{
/**
* @var ConcreteColleague1
*/
private $colleague1 ;
/**
* @var ConcreteColleague2
*/
privat $colleague2 ;
public function setColleague1 ( ConcreteColleague1 $colleague )
{
$this -> colleague1 = $colleague ;
}
public function setColleague2 ( ConcreteColleague2 $colleague )
{
$this -> colleague2 = $colleague ;
}
public function send ( $message , Colleague $colleague )
{
switch ( $colleague ) {
case $this -> colleague1 :
$this -> colleague2 -> notify ( $message );
bryde ;
case $this -> colleague2 :
$this -> colleague1 -> notify ( $message );
}
}
}
//colleague 1
class ConcreteColleague1 extends Colleague
{
public function notify ( $message )
{
echo sprintf ( "Colleague1 gets message: %s \n " , $message );
}
}
//colleague 2
class ConcreteColleague2 extends Colleague
{
public function notify ( $message )
{
echo sprintf ( "Colleague2 får besked: %s \n " , $message );
}
}
$mediator = ny ConcreteMediator ();
$collegue1 = new ConcreteColleague1 ( $mediator );
$collegue2 = new ConcreteColleague2 ( $mediator );
$mediator -> sætColleague1 ( $collegue1 );
$mediator -> setColleague2 ( $collegue2 );
$collegue1 -> send ( 'Hvordan har du det?' );
$collegue2 -> send ( 'Fin, tak!' );
Java-eksempel
Java kilde
offentlig abstrakt klasse Kollega {
beskyttet mægler mægler ;
offentlig kollega ( mediator mediator ) {
dette . mægler = mægler ;
}
public void send ( String message ) {
mediator . send ( besked , dette );
}
offentlig abstrakt void notify ( String message );
}
offentlig abstrakt klasse Mediator {
offentlig abstrakt void send ( streng besked , kollega afsender );
}
public class ConcreteColleague1 udvider Kollega {
public ConcreteColleague1 ( Mediator mediator ) {
super ( mediator );
}
@Override
public void notify ( String message ) {
System . ud . println ( "Kollega1 får besked: " + besked );
}
}
public class ConcreteColleague2 udvider Colleague {
public ConcreteColleague2 ( Mediator mediator ) {
super ( mediator );
}
@Override
public void notify ( String message ) {
System . ud . println ( "Colleague2 får besked: " + besked );
}
}
public class ConcreteMediator udvider Mediator {
privat BetonKollega1 kollega1 ;
privat ConcreteColleague2 colleague2 ;
public void setColleague1 ( ConcreteColleague1 colleague ) {
dette . kollega1 = kollega ;
}
public void setColleague2 ( ConcreteColleague2 colleague ) {
dette . kollega2 = kollega ;
}
@Override
public void send ( String message , Collegaafsender ) { if ( afsender . lig med ( colleague1 ) ) { colleague2 . underrette ( besked ); } andet { colleague1 . underrette ( besked ); } } }
offentlig klasse Main {
public static void main ( String [] args ) {
ConcreteMediator m = new ConcreteMediator ();
ConcreteColleague1 c1 = new ConcreteColleague1 ( m );
ConcreteColleague2 c2 = new ConcreteColleague2 ( m );
m . sætColleague1 ( c1 );
m . sætkollega2 ( c2 );
c1 . send ( "Hvordan har du det?" );
c2 . send ( "Fin, tak" );
}
}
Eksempel i C#
Kildetekst i
C#
// Mediator mønster - Strukturelt eksempel
ved hjælp af System ;
navneområde DoFactory.GangOfFour.Mediator.Structural
{
/// <resumé>
/// MainApp-opstartsklasse for Structural
/// Mediator Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Indgangspunkt i konsolapplikationen.
/// </summary>
static void Main ()
{
ConcreteMediator m = new ConcreteMediator ();
ConcreteColleague1 c1 = new ConcreteColleague1 ( m );
ConcreteColleague2 c2 = new ConcreteColleague2 ( m );
m . Kollega1 = c1 ;
m . Kollega2 = c2 ;
c1 . Send ( "Hvordan har du det?" );
c2 . Send ( "Fin, tak" );
// Vent på
brugerkonsollen . ReadKey ();
}
}
/// <summary>
/// 'Mediator' abstrakt klasse
/// </summary>
abstrakt klasse Mediator
{
public abstract void Send ( streng besked , Kollega kollega );
}
/// <summary>
/// 'ConcreteMediator'-klassen
/// </summary>
-klassen ConcreteMediator : Mediator
{
public ConcreteColleague1 Colleague1 { private get ; sæt ; }
public ConcreteColleague2 Colleague2 { private get ; sæt ; }
public override void Send ( streng besked , Kollega kollega )
{
if ( kollega == Kollega1 )
{
Kollega2 . underrette ( besked );
}
andet
{
Kollega1 . underrette ( besked );
}
}
}
/// <summary>
/// 'Colleague' abstrakt klasse
/// </summary>
abstrakt klasse Kollega
{
protected Mediator mediator ;
// Konstruktør
offentlig kollega ( mægler mediator )
{
dette . mægler = mægler ;
}
}
/// <summary>
/// En 'ConcreteColleague' klasse
/// </summary>
klasse ConcreteColleague1 : Colleague
{
// Constructor
public ConcreteColleague1 ( Mediator mediator )
: base ( mediator )
{
}
public void Send ( streng besked )
{
mediator . Send ( besked , dette );
}
public void Underretning ( strengmeddelelse ) { Konsol . _ WriteLine ( "Kollega1 får besked: " + besked ); } }
/// <summary>
/// En 'ConcreteColleague' klasse
/// </summary>
klasse ConcreteColleague2 : Colleague
{
// Constructor
public ConcreteColleague2 ( Mediator mediator )
: base ( mediator )
{
}
public void Send ( streng besked )
{
mediator . Send ( besked , dette );
}
public void Underretning ( strengmeddelelse ) { Konsol . _ WriteLine ( "Colleague2 får besked: " + besked ); } } }
Output
Kollega2 får besked : Hvordan har du det ?
Kollega1 får besked : Fint , tak
C++ eksempel
Kildetekst i
C++
#include <iostream>
#inkluder <streng>
klasse Kollega ;
klassemægler ; _
klasse ConcreteMediator ;
klasse BetonKollega1 ;
klasse ConcreteColleague2 ;
klassemægler _
{
offentligt :
virtuel void Send ( std :: streng const & besked , Kollega * kollega ) const = 0 ;
};
klasse kollega
{
beskyttet :
mægler * mægler_ ;
offentligt :
eksplicit kollega ( mægler * mediator ) : mediator_ ( mediator )
{
}
};
klasse ConcreteColleague1 : offentlig Kollega
{
offentligt :
eksplicit ConcreteColleague1 ( mægler * mægler ) : kollega ( mægler )
{
}
void Send ( std :: string const & message )
{
mediator_ -> Send ( meddelelse , denne );
}
void underretning ( std :: string const & message )
{
std :: cout << "Kollega1 får besked '" << besked << "'" << std :: endl ;
}
};
klasse ConcreteColleague2 : offentlig Kollega
{
offentligt :
eksplicit ConcreteColleague2 ( mægler * mægler ) : kollega ( mægler )
{
}
void Send ( std :: string const & message )
{
mediator_ -> Send ( meddelelse , denne );
}
void underretning ( std :: string const & message )
{
std :: cout << "Colleague2 får besked '" << besked << "'" << std :: endl ;
}
};
klasse ConcreteMediator : offentlig formidler
{
beskyttet :
ConcreteColleague1 * m_Colleague1 ;
ConcreteColleague2 * m_Colleague2 ;
offentligt :
void SetColleague1 ( ConcreteColleague1 * c )
{
m_Colleague1 = c ;
}
void SetColleague2 ( ConcreteColleague2 * c )
{
m_kollega2 = c ;
}
virtuel void Send ( std :: string const & message , kollega * colleague ) const
{
if ( kollega == m_Colleague1 )
{
m_Colleague2 -> Giv besked ( meddelelse );
}
else if ( kollega == m_Colleague2 )
{
m_Colleague1 -> Giv besked ( meddelelse );
}
}
};
int main ()
{
ConcreteMediator m ;
ConcreteColleague1 c1 ( & m );
ConcreteColleague2 c2 ( & m );
m . SetColleague1 ( & c1 );
m . SetColleague2 ( & c2 );
c1 . Send ( "Hvordan har du det?" );
c2 . Send ( "Fin, tak" );
std :: cin . få ();
returnere 0 ;
}
Produktion
Kollega2 får beskeden ' Hvordan har du det ? '
Kollega1 får beskeden " Fint , tak "
Python-eksempel
Kildekode i
Python
fra abc import ABCMeta , abstrakt metode
fra weakref import proxy
import inspicere
class Mediator ( metaclass = ABCMeta ):
"""
En abstrakt kommunikationskanal mellem kolleger
"""
@abstractmethod
def send ( selv , besked : str ) -> Ingen :
"""
Sender en besked mellem jævnaldrende
"""
pass
klassekollega ( metaclass = ABCMeta ) : """ En abstrakt arbejder, der ikke har noget imod at chatte med sine kolleger """
def __init__ ( self , mediator : Mediator ) -> Ingen :
"""
Konstruktør.
:param mediator: kommunikationskanal med kolleger
""
" self ._mediator = proxy ( mediator )
@abstractmethod
def send ( selv , besked : str ) -> Ingen :
"""
Send besked via kommunikationskanal
"""
pass
@abstractmethod
def modtage ( selv , besked : str ) -> Ingen :
"""
Modtag besked via kommunikationskanal
"""
pass
klasse SkypeBetweenTwoColleagues ( Mediator ):
"""
Skype-kanal til kommunikation mellem to personer
"""
def __init__ ( self ) -> Ingen :
"""
Konstruktør.
"""
self . _first = Ingen
selv . _second = Ingen
def set_first ( self , first : Colleague ) -> Ingen :
"""
Tildeler den første deltager i samtalen
"""
selv til kanalen . _første = først
def set_second ( selv , anden : Kollega ) -> Ingen :
"""
Knytter den anden deltager i samtalen
"""
selv til kanalen . _sekund = sekund
def send ( selv , besked : str ) -> Ingen :
afsender = inspicere . nuværende frame () . f_tilbage . f_locals [ 'selv' ]
modtager = selv . _first hvis afsender == selv . _second else self . _anden
modtager . modtage ( besked )
klasseregning ( kollega ) :
def send ( selv , besked : str ) -> Ingen :
selv . _mægler . send ( besked )
def modtage ( self , message : str ) -> Ingen :
print ( 'Bill modtaget beskeden: {} ' . format ( message ))
klasse Steve ( kollega ):
def send ( selv , besked : str ) -> Ingen :
selv . _mægler . send ( besked )
def receive ( self , message : str ) -> None :
print ( 'Steve læste beskeden på Skype: {} ' . format ( message ))
if __name__ == '__main__' :
print ( 'OUTPUT:' )
skype = SkypeBetweenTwoColleagues ()
bill = Bill ( skype )
steve = Steve ( skype )
skype . set_first ( bill . )
skype . set_second ( steve )
bill . send ( 'Kom på arbejde, slacker!' )
steve . send ( 'Nej' )
'''
OUTPUT:
Steve læste en Skype-besked: Kom på arbejde, sladder!
Bill modtog beskeden: Nej
'''
Delphi eksempel
Kildetekst i
Delphi
program MediatorEksempel ;
{$APPTYPE KONSOL}
type
IColleague = interface
procedure Send ( AMessage : string ) ;
procedure Give besked ( AMessage : streng ) ;
ende ;
TMediator = klasseprocedure
Send ( AMessage : string ; ACollegue : IColleague ) ; _ virtuel ; abstrakt ; ende ;
TConcreteMediator = klasse ( TMediator )
public
FCollegue1 : IColleague ;
FCollegue2 : IColleague ;
procedure Send ( AMessage : string ; ACollegue : IColleague ) ; tilsidesætte ;
ende ;
TColleague = klasse ( TInterfacedObject , IColleague )
offentlig
FMediator : TMediator ;
constructor Opret ( AMediator : TMediator ) ;
procedure Send ( AMessage : streng ) ; virtuel ; abstrakt ;
procedure Give besked ( AMessage : streng ) ; virtuel ; abstrakt ;
ende ;
ConcreteColleague1 = klasse ( TColleague )
procedure Send ( AMessage : string ) ; tilsidesætte ;
procedure Give besked ( AMessage : streng ) ; tilsidesætte ;
ende ;
ConcreteColleague2 = klasse ( TColleague )
procedure Send ( AMessage : string ) ; tilsidesætte ;
procedure Give besked ( AMessage : streng ) ; tilsidesætte ;
ende ;
{ TConcreteMediator }
procedure TConcreteMediator . Send ( AMessage : string ; ACollegue : IColleague ) ;
begynde
hvis ACollegue = FCollegue1 så
FCollegue2 . Giv besked ( AMessage )
andet
F Kollege1 . Giv besked ( AMessage ) ;
ende ;
{TColleague}
konstruktør TColleague . Opret ( AMediator : TMediator ) ;
start
FMediator := AMediator ;
ende ;
{ConcreteColleague1}
procedure ConcreteColleague1 . Send ( AMessage : string ) ;
start
FMediator . Send ( AMeddel , Selv ) ;
ende ;
procedure ConcreteColleague1 . Giv besked ( AMessage : string ) ;
start
Writeln ( 'Colleague1 får besked: ' + AMessage ) ;
ende ;
{ConcreteColleague2}
procedure ConcreteColleague2 . Send ( AMessage : string ) ;
start
FMediator . Send ( AMeddel , Selv ) ;
ende ;
procedure ConcreteColleague2 . Giv besked ( AMessage : string ) ;
start
Writeln ( 'Colleague2 får besked: ' + AMessage ) ;
ende ;
var
Mediator : TConcreteMediator ;
Kollega1 : BetonKollega1 ;
Kollega2 : ConcreteColleague2 ;
start
Mediator := TConcreteMediator . skabe ;
Kollega1 := KonkretKollega1 . Opret ( mægler ) ;
Kollega2 := BetonKollega2 . Opret ( mægler ) ;
mægler . FCollegue1 := Kollega1 ;
mægler . FCollegue2 := Kollege2 ;
Kollega 1 . Send ( 'Hvordan har du det?' ) ;
Kollega 2 . Send ( 'Fin, tak' ) ;
readln ;
ende .
Links