本文编辑整理自:
http://blog.csdn.net/haiyan0106/article/details/1651719
一、什么是中介者模式
Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用。
关于 Mediator模式的更多理论知识请参考《 设计模式之Mediator(中介者)模式(理论篇)》
二、何时使用中介者模式
各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,可以降低系统的复杂性,提高可修改扩展性。
在下列情况下使用中介者模式:
1、一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
2、一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
3、想定制一个分布在多个类中的行为,而又不想生成太多的子类。
三、举例
Mediator模式是GoF的23种设计模式中较为容易理解的一个,我们在平时的应用中也会经常用到,但可能不会有意去抽象出一个完整的Mediator类,因为要设计一个可复用又可扩展的Mediator是很不容易的。
Mediator模式的主要作用在于为多个对象之间的交互提供一种媒介,以简化对象之间的耦合关系。下面用两个实例来说明Mediator模式的应用。
3.1、ChatRoom(聊天室)示例
聊天室大家想必都知道,在下面的示例中,我们尝试实现一个布告栏式的ChatRoom,任何人想要发送消息给其他人,只需将消息发送给ChatRoom对象,由ChatRoom负责数据的转发,而不是直接与消息的接收者交互。后面的笔记中将从Observer模式的角度来解决ChatRoom问题。
#include <iostream>
#include <string>
#include <map>
using namespace std ;
class Participant ;
// "AbstractMediator"
struct IChatroom
{
// Methods
virtual void Register ( Participant * participant ) = 0 ;
virtual void Send ( string & from , string & to , string & message ) = 0 ;
};
// "AbstractColleague"
class Participant
{
friend class Chatroom ;
// Fields
private :
IChatroom * pChatroom ;
string name ;
// Constructors
public :
/*Participant()
{
}*/
Participant ( const char * name )
{
this ->name = name ;
}
virtual ~Participant ()
{
}
// Methods
virtual void Send ( string & to , string & message )
{
pChatroom ->Send ( name , to , message );
}
virtual void Receive ( string & from , string & message )
{
cout << from .c_str () << " to " << name .c_str () << " : [" << message .c_str () << "]" << endl ;
}
};
// More ConcreteColleague, omitted...
// "ConcreteMediator"
class Chatroom : public IChatroom
{
// Fields
private :
map <string , Participant *> mapParticipants ; // nickname to Participant map
// Methods
public :
void Register ( Participant * pParticipant )
{
mapParticipants [ pParticipant ->name ] = pParticipant ;
pParticipant ->pChatroom = this ;
}
void Send ( string & from , string & to , string & message )
{
map <string , Participant *>::iterator ptr ;
ptr = mapParticipants .find (to );
if ( ptr != mapParticipants .end () )
{
Participant * pto = (*ptr ).second ;
pto ->Receive ( from , message );
}
}
};
int main ()
{
// Create chatroom
Chatroom c ;
// Create 'chatters' and register them
Participant George ( "George" );
Participant Paul ( "Paul" );
Participant Ringo ( "Ringo" );
c .Register ( &George );
c .Register ( &Paul );
c .Register ( &Ringo );
// Chatting participants
George .Send ( string ( "Paul" ), string ( "Hi Paul!" ) );
Paul .Send ( string ( "Ringo" ), string ( "Good Morning!" ) );
Ringo .Send ( string ( "George" ), string ( "Hi Friend!" ) );
return 0 ;
}
3.2、多线程Producer-Consumer(生产者和消费者示例)
以下是一个多线程Producer-Comsumer的例子,在该示例中,由于无法在多个Producer、Cosumer之间建立直接的联系,因此,通过Mediator类来完成这种信息交互,当Producer要Produce时,只需与Mediator进行交互,以查询是否有空的Slot可供存放Product,而Comsumer要Comsume时,也只需与Mediator进行交互,以查询是否有Product可供Comsume。
以下是该示例的Java实现:
import java .util .*;
class Product {
int id ;
Product ( int id ) {
this .id = id ;
}
}
class Mediator {
private boolean stopFlag = false;
private Stack slot = new Stack ();
private int slotCount ;
public Mediator ( int slotCount ) {
this .slotCount = slotCount ;
}
public boolean stop () {
return stopFlag ;
}
public void stop (boolean flag ) {
stopFlag = true;
}
public boolean put (Product product ) {
synchronized ( slot ) { // or synchronized on Mediator.class, but on slot is better and reasonable
if ( slot .size () >= slotCount ) {
return false;
}
slot .push ( product );
}
return true;
}
public Product get () {
synchronized ( slot ) {
if ( slot .empty () )
return null ;
Product product = (Product )slot .pop ();
return product ;
}
}
}
class Producer extends Thread {
private Mediator med ;
private int id ;
private static int num = 1 ;
public Producer (Mediator m ) {
med = m ;
id = num ++;
}
public void run () {
Product product ;
while ( !med .stop () ) {
product = new Product (( int ) (Math .random () * 100 ));
synchronized (System .out ) {
System .out .println ( "Producer[" + id + "] produces Product["
+ product .id + "]" );
}
while ( !med .stop () && !med .put (product ) ) { // if put failed, try to put again and again.
try {
sleep ( 100 );
} catch (InterruptedException ie ) {
}
}
try {
sleep ( 100 );
} catch (InterruptedException ie ) {
}
}
}
}
class Consumer extends Thread {
private Mediator med ;
private int id ;
private static int num = 1 ;
public Consumer (Mediator m ) {
med = m ;
id = num ++;
}
public void run () {
Product product ;
while ( !med .stop () ) {
product = med .get ();
if ( product != null ) {
synchronized (System .out ) {
System .out .println ( "Consumer[" + id + "] is consuming Product["
+ product .id + "]" );
}
}
try {
sleep ( 100 );
} catch (InterruptedException ie ) {
}
}
}
}
class MediatorDemo {
public static void main (String [] args ) {
Mediator med = new Mediator ( 2 );
Thread thread [] = { new Producer (med ), new Producer (med ),
new Consumer (med ), new Consumer (med ), new Consumer (med ) };
for ( int i = 0 ; i < thread .length ; i ++)
thread [i ].start ();
// before stop all threads, sleep 1 second
try {
Thread .sleep ( 1000 );
} catch (InterruptedException ie ) {
}
med .stop (true);
// Wait for all threads to return
try {
for ( int i = 0 ; i < thread .length ; i ++) {
thread [i ].join ();
}
} catch (InterruptedException ie ) {
}
}
}
结束!
http://blog.csdn.net/haiyan0106/article/details/1651719
一、什么是中介者模式
Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用。
关于 Mediator模式的更多理论知识请参考《 设计模式之Mediator(中介者)模式(理论篇)》
二、何时使用中介者模式
各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,可以降低系统的复杂性,提高可修改扩展性。
在下列情况下使用中介者模式:
1、一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
2、一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
3、想定制一个分布在多个类中的行为,而又不想生成太多的子类。
三、举例
Mediator模式是GoF的23种设计模式中较为容易理解的一个,我们在平时的应用中也会经常用到,但可能不会有意去抽象出一个完整的Mediator类,因为要设计一个可复用又可扩展的Mediator是很不容易的。
Mediator模式的主要作用在于为多个对象之间的交互提供一种媒介,以简化对象之间的耦合关系。下面用两个实例来说明Mediator模式的应用。
3.1、ChatRoom(聊天室)示例
聊天室大家想必都知道,在下面的示例中,我们尝试实现一个布告栏式的ChatRoom,任何人想要发送消息给其他人,只需将消息发送给ChatRoom对象,由ChatRoom负责数据的转发,而不是直接与消息的接收者交互。后面的笔记中将从Observer模式的角度来解决ChatRoom问题。
#include <iostream>
#include <string>
#include <map>
using namespace std ;
class Participant ;
// "AbstractMediator"
struct IChatroom
{
// Methods
virtual void Register ( Participant * participant ) = 0 ;
virtual void Send ( string & from , string & to , string & message ) = 0 ;
};
// "AbstractColleague"
class Participant
{
friend class Chatroom ;
// Fields
private :
IChatroom * pChatroom ;
string name ;
// Constructors
public :
/*Participant()
{
}*/
Participant ( const char * name )
{
this ->name = name ;
}
virtual ~Participant ()
{
}
// Methods
virtual void Send ( string & to , string & message )
{
pChatroom ->Send ( name , to , message );
}
virtual void Receive ( string & from , string & message )
{
cout << from .c_str () << " to " << name .c_str () << " : [" << message .c_str () << "]" << endl ;
}
};
// More ConcreteColleague, omitted...
// "ConcreteMediator"
class Chatroom : public IChatroom
{
// Fields
private :
map <string , Participant *> mapParticipants ; // nickname to Participant map
// Methods
public :
void Register ( Participant * pParticipant )
{
mapParticipants [ pParticipant ->name ] = pParticipant ;
pParticipant ->pChatroom = this ;
}
void Send ( string & from , string & to , string & message )
{
map <string , Participant *>::iterator ptr ;
ptr = mapParticipants .find (to );
if ( ptr != mapParticipants .end () )
{
Participant * pto = (*ptr ).second ;
pto ->Receive ( from , message );
}
}
};
int main ()
{
// Create chatroom
Chatroom c ;
// Create 'chatters' and register them
Participant George ( "George" );
Participant Paul ( "Paul" );
Participant Ringo ( "Ringo" );
c .Register ( &George );
c .Register ( &Paul );
c .Register ( &Ringo );
// Chatting participants
George .Send ( string ( "Paul" ), string ( "Hi Paul!" ) );
Paul .Send ( string ( "Ringo" ), string ( "Good Morning!" ) );
Ringo .Send ( string ( "George" ), string ( "Hi Friend!" ) );
return 0 ;
}
3.2、多线程Producer-Consumer(生产者和消费者示例)
以下是一个多线程Producer-Comsumer的例子,在该示例中,由于无法在多个Producer、Cosumer之间建立直接的联系,因此,通过Mediator类来完成这种信息交互,当Producer要Produce时,只需与Mediator进行交互,以查询是否有空的Slot可供存放Product,而Comsumer要Comsume时,也只需与Mediator进行交互,以查询是否有Product可供Comsume。
以下是该示例的Java实现:
import java .util .*;
class Product {
int id ;
Product ( int id ) {
this .id = id ;
}
}
class Mediator {
private boolean stopFlag = false;
private Stack slot = new Stack ();
private int slotCount ;
public Mediator ( int slotCount ) {
this .slotCount = slotCount ;
}
public boolean stop () {
return stopFlag ;
}
public void stop (boolean flag ) {
stopFlag = true;
}
public boolean put (Product product ) {
synchronized ( slot ) { // or synchronized on Mediator.class, but on slot is better and reasonable
if ( slot .size () >= slotCount ) {
return false;
}
slot .push ( product );
}
return true;
}
public Product get () {
synchronized ( slot ) {
if ( slot .empty () )
return null ;
Product product = (Product )slot .pop ();
return product ;
}
}
}
class Producer extends Thread {
private Mediator med ;
private int id ;
private static int num = 1 ;
public Producer (Mediator m ) {
med = m ;
id = num ++;
}
public void run () {
Product product ;
while ( !med .stop () ) {
product = new Product (( int ) (Math .random () * 100 ));
synchronized (System .out ) {
System .out .println ( "Producer[" + id + "] produces Product["
+ product .id + "]" );
}
while ( !med .stop () && !med .put (product ) ) { // if put failed, try to put again and again.
try {
sleep ( 100 );
} catch (InterruptedException ie ) {
}
}
try {
sleep ( 100 );
} catch (InterruptedException ie ) {
}
}
}
}
class Consumer extends Thread {
private Mediator med ;
private int id ;
private static int num = 1 ;
public Consumer (Mediator m ) {
med = m ;
id = num ++;
}
public void run () {
Product product ;
while ( !med .stop () ) {
product = med .get ();
if ( product != null ) {
synchronized (System .out ) {
System .out .println ( "Consumer[" + id + "] is consuming Product["
+ product .id + "]" );
}
}
try {
sleep ( 100 );
} catch (InterruptedException ie ) {
}
}
}
}
class MediatorDemo {
public static void main (String [] args ) {
Mediator med = new Mediator ( 2 );
Thread thread [] = { new Producer (med ), new Producer (med ),
new Consumer (med ), new Consumer (med ), new Consumer (med ) };
for ( int i = 0 ; i < thread .length ; i ++)
thread [i ].start ();
// before stop all threads, sleep 1 second
try {
Thread .sleep ( 1000 );
} catch (InterruptedException ie ) {
}
med .stop (true);
// Wait for all threads to return
try {
for ( int i = 0 ; i < thread .length ; i ++) {
thread [i ].join ();
}
} catch (InterruptedException ie ) {
}
}
}
结束!