设计模式之Mediator(中介者)模式(应用篇)
2012-04-11 22:22
831 查看
本文编辑整理自:
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) {
}
}
}
结束!
相关文章推荐
- Java 设计模式 之 中介者模式(Mediator)
- 我所理解的设计模式(C++实现)——中介者模式(Mediator Pattern)
- 设计模式--行为型-Mediator(中介者)
- 设计模式之中介者模式(Mediator)
- 设计模式之二十一:中介者模式(Mediator)
- 设计模式之---中介者模式(Mediator Design Pattern)
- Mediator(中介者)设计模式
- 设计模式(17)——中介者 Mediator
- C#面向对象模式设计第十七讲:Mediator 中介者模式(行为型模式)
- 23种设计模式--中介者模式-Mediator Pattern
- 设计模式之Mediator(中介者)
- 设计模式 笔记 中介者模式 Mediator
- 23种设计模式之中介者模式(Mediator)
- 设计模式之中介者模式(Mediator)
- 23种设计模式(17)_行为型_中介者模式(Mediator Pattern)
- 设计模式(行为型模式) ----- 中介者模式(Mediator)
- 设计模式笔记21:中介者模式(Mediator Pattern)
- 设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)
- 设计模式(十六)中介者模式(Mediator)-行为型
- 设计模式之Mediator(中介者)