1 Mediator Pattern 中介者模式
目的:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互;
实现:定义一个对象,该对象封装了一组对象交互的方式。
1.在多个类相互耦合,形成了网状结构时使用,将网状结构分离为星型结构;
2.中介者类用于协调其他对象/类之间相互调用;
2 实现
代码场景:买家、卖家在淘宝上交易,淘宝相当于中介者角色;
2.1 代码实现
抽象同事类角色
public abstract class AbstractCustomer {
// 客户名
protected String name;
// 账户默认100元
protected int account = 100;
// 心情
protected String mood;
// 事件方法
public abstract void deal(AbstractMediator taoBao, String doSomeThing, int money);
public String getName() {
return name;
}
public String getMood() {
return mood;
}
public void setMood(String mood) {
this.mood = mood;
}
public int getAccount() {
return account;
}
}
具体同事类角色:淘宝买家
public class Buyer extends AbstractCustomer {
public Buyer() {
name = "淘宝买家";
}
@Override
public synchronized void deal(AbstractMediator taoBao, String doSomeThing, int money) {
if ("购买".equals(doSomeThing)) {
// 事件只对对象本身造成影响
mood = "good";
account = account - money;
// 通过中介者影响对方
taoBao.buyerAffectSeller(doSomeThing, money);
}
if ("退货".equals(doSomeThing)) {
// 事件只对对象本身造成影响
mood = "bad";
account = account + money;
// 通过中介者影响对方
taoBao.buyerAffectSeller(doSomeThing, money);
}
}
}
具体同事类角色:淘宝卖家
public class Seller extends AbstractCustomer {
public Seller() {
name = "淘宝卖家";
}
@Override
public synchronized void deal(AbstractMediator taoBao, String doSomeThing, int money) {
if ("购买".equals(doSomeThing)) {
// 事件只对对象本身造成影响
mood = "good";
account = account + money;
// 通过中介者影响对方
taoBao.sellerAffectBuyer(doSomeThing, money);
}
if ("退货".equals(doSomeThing)) {
// 事件只对对象本身造成影响
mood = "bad";
account = account - money;
// 通过中介者影响对方
taoBao.sellerAffectBuyer(doSomeThing, money);
}
}
}
抽象中介者角色
public abstract class AbstractMediator {
protected AbstractCustomer buyer;
protected AbstractCustomer seller;
public AbstractMediator(AbstractCustomer buyer, AbstractCustomer seller) {
this.buyer = buyer;
this.seller = seller;
}
// 买家影响卖家
public abstract void buyerAffectSeller(String doSomeThing, int money);
// 卖家影响买家
public abstract void sellerAffectBuyer(String doSomeThing, int money);
}
具体中介者角色:淘宝
public class TaoBao extends AbstractMediator {
public TaoBao(AbstractCustomer buyer, AbstractCustomer seller) {
super(buyer, seller);
}
@Override
public void buyerAffectSeller(String doSomeThing, int money) {
// 买家对卖家的关系
seller.setMood(buyer.getMood());
if ("购买".equals(doSomeThing)) {
seller.account = seller.account + money;
// 打印展示相互影响的结果
System.out.println(buyer.name + "进行了[" + doSomeThing + "],花了[" + money + "元],心情很[" + buyer.mood
+ "],当前账户余额[" + buyer.account + "元]");
System.out.println(seller.getName() + "收到[" + doSomeThing + "]请求,收到[" + money + "元],心情很[" + seller.mood
+ "],当前账户余额[" + seller.getAccount() + "元]");
}
if ("退货".equals(doSomeThing)) {
seller.account = seller.account - money;
// 打印展示相互影响的结果
System.out.println(buyer.name + "进行了[" + doSomeThing + "],退了[" + money + "元],心情很[" + buyer.mood
+ "],当前账户余额[" + buyer.account + "元]");
System.out.println(seller.getName() + "收到[" + doSomeThing + "]请求,收到[" + money + "元],心情很[" + seller.mood
+ "],当前账户余额[" + seller.getAccount() + "元]");
}
}
@Override
public void sellerAffectBuyer(String doSomeThing, int money) {
// 卖家对买家的关系
buyer.setMood(seller.getMood());
if ("购买".equals(doSomeThing)) {
buyer.account = buyer.account - money;
// 打印展示相互影响的结果
System.out.println(
seller.name + "推销成功,收到[" + money + "元],心情很[" + seller.mood + "],当前账户余额[" + seller.account + "元]");
System.out.println(buyer.getName() + "进行了[" + doSomeThing + "],花了[" + money + "元],心情很[" + seller.mood
+ "],当前账户余额[" + buyer.getAccount() + "元]");
}
if ("退货".equals(doSomeThing)) {
buyer.account = buyer.account + money;
// 打印展示相互影响的结果
System.out.println(seller.name + "收到[" + doSomeThing + "]请求,退了[" + money + "元],心情很[" + seller.mood
+ "],当前账户余额[" + seller.account + "元]");
System.out.println(buyer.getName() + "进行了[" + doSomeThing + "],收到[" + money + "元],心情很[" + buyer.mood
+ "],当前账户余额[" + buyer.getAccount() + "元]");
}
}
}
2.2 涉及角色
在中介者模式结构图中包含如下几个角色:
Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。
中介者模式的核心在于中介者类的引入,在中介者模式中,中介者类承担了两方面的职责:
(1) 中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,可通过中介者来实现间接调用。该中转作用属于中介者在结构上的支持。
(2) 协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致的和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。
2.3 调用
调用者:
public class Client {
public static void main(String[] args) {
// 买家
Buyer buyer = new Buyer();
// 卖家
Seller seller = new Seller();
// 中介者
AbstractMediator taoBao = new TaoBao(buyer, seller);
System.out.println("剧情一--------买家发起购买----------");
buyer.deal(taoBao, "购买", 20);
System.out.println("剧情二--------买家发起退货----------");
buyer.deal(taoBao, "退货", 20);
System.out.println("剧情三--------卖家发起推销----------");
seller.deal(taoBao, "购买", 30);
System.out.println("剧情四--------卖家发起退货----------");
seller.deal(taoBao, "退货", 30);
}
}
结果:
剧情一--------买家发起购买----------
淘宝买家进行了[购买],花了[20元],心情很[good],当前账户余额[80元]
淘宝卖家收到[购买]请求,收到[20元],心情很[good],当前账户余额[120元]
剧情二--------买家发起退货----------
淘宝买家进行了[退货],退了[20元],心情很[bad],当前账户余额[100元]
淘宝卖家收到[退货]请求,收到[20元],心情很[bad],当前账户余额[100元]
剧情三--------卖家发起推销----------
淘宝卖家推销成功,收到[30元],心情很[good],当前账户余额[130元]
淘宝买家进行了[购买],花了[30元],心情很[good],当前账户余额[70元]
剧情四--------卖家发起退货----------
淘宝卖家收到[退货]请求,退了[30元],心情很[bad],当前账户余额[100元]
淘宝买家进行了[退货],收到[30元],心情很[bad],当前账户余额[100元]
参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.