您的位置:首页 > 运维架构 > 网站架构

"围观"设计模式(25)--行为型之中介者模式(Mediator Pattern)

2016-07-09 15:45 701 查看
用一个对象封装一系列的对象交互,中介者使对象不需要显示的相互作用,从而使其耦合松散,而且可以独立的改变他们之间的独立。



个人理解

当多个对象之间存在着过多的耦合时,可以通过中介者模式进行解耦,将具体的对象之间的耦合转为中介者与具体对象的耦合,假如说之前是三个对象的相互之间的耦合,转为中介者与具体类的耦合之后,从耦合性上大大的降低了,这样如果再来对其进行修改的话,那么变更部分主要在中介者部分,从而使得该结构更加稳定。




角色分析

中介者角色分以下几个部分:

1. Mediator抽象中介者角色:抽象中介者角色定义统一的接口,用于各同事角色之间的通信。

2. Concrete Mediator具体中介者角色:具体中介者角色通过协调各同事角色实现写作行为,依赖于各同事角色。

3. Colleague同事角色:每个同事类的任务中,包括自身需要完成的功能,以及自己完不成要交给中介者进行其余处理的部分功能。




案例解析

案例一:购销系统应用中介者模式

案例背景介绍

由公司购销系统来讲,购入商品的时候,库存需要相应的增加,此处属于依赖其他对象的关系。需要清仓的时候,一方面,需要停止进货,打折促销完成清仓任务。从这几部来看实体类(Purchase、Sale、Store)三者之间如果不采用中介者模式的时候,需要在完成购入的任务时,使得Purchase类依赖Store类。在完成清仓并促销等任务时,使得Store中依赖Purchase类和Sale类。这样的依赖关系就显得过于复杂,而且不容易管理。

使用中介者模式之后,就会使得三者之间的依赖关系纯粹而简单,只与中介者类耦合,其余的操作也可以在中介者类中进行完成。这样既方便管理与维护,也降低了耦合度提高了稳定性。



主要代码

相当于同事角色抽象类。定义公共的属性和制定构造方法。




public abstract class AbstractEmployee {

protected AbstractMediator mediator;

public AbstractEmployee(){}

public AbstractEmployee(AbstractMediator mediator) {
this.mediator = mediator;
}

}
具体同事角色实现类
public class PurchaseMan extends AbstractEmployee {

public PurchaseMan(){

}

public PurchaseMan(AbstractMediator mediator) {
super(mediator);
}

public void buy(int i) {
this.mediator.executor("buy", i);
}

public void stopBuy() {
System.out.println("停止购买");
}

}

public class SaleMan extends AbstractEmployee {

public SaleMan(){}

public SaleMan(AbstractMediator mediator) {
super(mediator);
}

public int getStatus() {
Random random = new Random();
int num = random.nextInt(120);
return num;
}

public void sale(Integer num) {
this.mediator.executor("sale", num);
}
}

public class StoreMan extends AbstractEmployee {

private int num = 100;

public StoreMan() {

}

public StoreMan(AbstractMediator mediator) {
super(mediator);
}

public void increaseStore(Integer num) {

this.num += num;
}

public Integer getNum() {

return this.num;
}

public void clearStore() {

this.mediator.executor("sell", this.num);
}

public void decreaseStore(Integer num2) {

this.num -= num2;
}

}

中介者角色抽象类:抽象中介者角色定义统一的接口,用于各同事角色之间的通信。



public abstract class AbstractMediator {

protected static PurchaseMan purchase = new PurchaseMan();
protected static SaleMan sale = new SaleMan();
protected static StoreMan store = new StoreMan();

public abstract void executor(String exeStr, Object...obj);
}
Concrete Mediator具体中介者角色:具体中介者角色通过协调各同事角色实现写作行为,依赖于各同事角色。



public class Mediator extends AbstractMediator {

@Override
public void executor(String exeStr, Object... obj) {
// 购入
if("buy".equals(exeStr)) {
this.buySomething((Integer)obj[0]);
}
// 卖出
else if("sell".equals(exeStr)) {
this.sellSomething((Integer)obj[0]);
}
// 清仓
else if("clear".equals(exeStr)) {
this.clear();
}
// 打折促销
else if("sale".equals(exeStr)) {
this.sale((Integer)obj[0]);
}

}

private void sale(int num) {
System.out.println("便宜卖出" + num);
}

private void clear() {
System.out.println("clear --- start");
if(store.getNum() > 0) {
System.out.println("清仓>>" + store.getNum());
purchase.stopBuy();
sale.sale(store.getNum());
store.decreaseStore(store.getNum());
}
else {
System.out.println("已经清仓");
}
System.out.println("clear --- stop");
}

private void sellSomething(Integer num) {

System.out.println("sell ---- start");
if(store.getNum() <= num) {

System.out.println("买入" + (num - store.getNum()));
System.out.println("清仓");
purchase.buy(num - store.getNum());
store.clearStore();
}
else {
System.out.println("卖出" + num);
store.decreaseStore(num);
}
System.out.println("sell ---- end");
}

private void buySomething(Integer num) {
System.out.println("buy ---- start");
if(sale.getStatus() > 100) {
System.out.println("购入" + num);
store.increaseStore(num);
}
else{
System.out.println("购入" + num / 3);
store.increaseStore(num / 3);
}
System.out.println("buy ---- end");
}

}

测试类



public class MainTest {

public static void main(String[] args) {

Mediator mediator = new Mediator();

PurchaseMan purchase = new PurchaseMan(mediator);
purchase.buy(100);

SaleMan sale = new SaleMan(mediator);
sale.sale(100);

StoreMan store = new StoreMan(mediator);
store.clearStore();
}
}

案例二:模拟飞机场调度

案例背景

飞机场作为各个飞机落地时的中介是非常重要的,如果当前跑道上有飞机在降落,那么达到的其他的飞机不能进行降落,得等待该飞机完成降落后,刚到达的飞机才能进行安全的降落。本例通过多线程的方式进行中介者模式的运用。模拟飞机的降落过程。

主要代码

相当于同事类的抽象类。定义了中介者以及 必要的一些飞机落地的方法。




public abstract class Airplane {

protected static AriportMediator mediator = new AriportMediator();
/**
* 准备降落
*/
public abstract  void prepareLanded();

/**
* 检查是否安全
*/
public abstract boolean checkIsSafe();

/**
* 着陆
*/
public abstract void landing();

/**
* 继续飞行,直到确认安全为止
*/
public abstract void continueToFly();

public void landingMethod(){
this.prepareLanded();
if(this.checkIsSafe()){
landing();
}else{
continueToFly();
}

}
}

public class CNAirPlane extends Airplane{

@Override
public void prepareLanded() {
System.out.println("CNAirPlane--准备着陆!");
this.mediator.setAirPlaneWaitingLoading(this);
}

@Override
public synchronized boolean checkIsSafe() {
return this.mediator.checkIsSafe();
}

@Override
public synchronized void landing() {
this.mediator.setStatus(0);
System.out.println("CNAirPlane--正在着陆!");
try {
new Thread().sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
this.mediator.removeAirplane(this);
System.out.println("CNAirPlane--着陆完成!");
this.mediator.setStatus(1);
}

@Override
public void continueToFly() {
System.out.println("CNAirPlane--继续飞行!");
while(true){
if(this.mediator.checkIsSafe()){
landing();
break;
}
}
}

}

public class CNSHAirPlane extends Airplane{

@Override
public void prepareLanded() {
System.out.println("CNSHAirPlane--准备着陆!");
this.mediator.setAirPlaneWaitingLoading(this);
}

@Override
public boolean checkIsSafe() {
return this.mediator.checkIsSafe();
}

@Override
public synchronized void landing() {
System.out.println("CNSHAirPlane--正在着陆!");
try {
new Thread().sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
this.mediator.setStatus(0);
this.mediator.removeAirplane(this);
System.out.println("CNSHAirPlane--着陆完成!");
}

@Override
public void continueToFly() {
System.out.println("CNSHAirPlane--继续飞行!");
while(true){
if(this.mediator.checkIsSafe()){
landing();
break;
}
}
}
}
中介者角色,完成多个飞机角色的交互,协调之间的降落关系,使得飞机可以安全的落地。
public class AriportMediator {

// 记录飞机申请着陆的序列
private static List<Object> airPlaneWaitingLoading = new ArrayList<Object>();
// 飞机着陆状态0:表示不可以着陆,1表示可以着陆。
private static int airPlaneLoadingStatus = 1;

public static List<Object> getAirPlaneWaitingLoading() {
return airPlaneWaitingLoading;
}

public static synchronized void setAirPlaneWaitingLoading(Object airPlane) {
airPlaneWaitingLoading.add(airPlane);
// System.out.println(airPlaneWaitingLoading);
}

public static synchronized void removeAirplane(Object airPlane) {
airPlaneWaitingLoading.remove(airPlane);
// System.out.println(airPlaneWaitingLoading);
}

public synchronized boolean checkIsSafe() {
// 正在准备着陆的飞机
if(airPlaneWaitingLoading != null && airPlaneWaitingLoading.size() > 1 || airPlaneLoadingStatus == 0){
return false;
}
else{
return true;
}
}

public synchronized void setStatus(int status){
airPlaneLoadingStatus = status;
// System.out.println("状态:" + airPlaneLoadingStatus);
}
public int getStatus(){
return airPlaneLoadingStatus;
}

}

测试类



public class MainTest {

public static void main(String[] args) {
new Thread(new Runnable() {

@Override
public void run() {
Airplane airPlane = new CNAirPlane();
airPlane.landingMethod();
}
}).start();

new Thread(new Runnable() {

@Override
public void run() {
Airplane airPlane2 = new CNSHAirPlane();
airPlane2.landingMethod();
}
}).start();

}
}


中介者模式优点

减少类之间的依赖关系,把原来的一对多的依赖关系变成一对一的依赖关系,减少了依赖降低了耦合度,提高了稳定性。

中介者模式缺点

导致中介者类膨胀,逻辑过于复杂化,同事类越多,那么中介者中逻辑越复杂。


设计模式代码下载

设计模式源码下载






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息