设计模式详解—中介者模式
程序员文章站
2022-03-03 09:49:23
一、场景问题设计一套买房与卖房的交互程序。二、传统解决方案最直观的做法是定义卖方和买方的实体,二者直接进行信息交互。但是随着买方和卖方的人数新增,实体之间的交互会变得错综复杂,直接交互的设计方案会导致系统的通信链路交错复杂,且实体之间耦合过多,维护困难。因此我们可以采用中间层(中介)的方式来简化交互流程。即每个客户都只与中介交互,由中介来负责传递消息,使得各个实体间解耦,较少交互上的不便性。(即现在的房地产中介公司,当然缺点就是增加了中介费)。三、模式剖析1、模式定义中介者模式(Mediato...
一、场景问题
设计一套买房与卖房的交互程序。
二、传统解决方案
最直观的做法是定义卖方和买方的实体,二者直接进行信息交互。但是随着买方和卖方的人数新增,实体之间的交互会变得错综复杂,直接交互的设计方案会导致系统的通信链路交错复杂,且实体之间耦合过多,维护困难。因此我们可以采用中间层(中介)的方式来简化交互流程。即每个客户都只与中介交互,由中介来负责传递消息,使得各个实体间解耦,较少交互上的不便性。(即现在的房地产中介公司,当然缺点就是增加了中介费)。
三、模式剖析
1、模式定义
中介者模式(Mediator Pattern):定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。
2、模式结构
中介者模式一般包含如下角色
-
Mediator
:抽象中介者角色它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
abstract class Mediator { protected ArrayList<Colleague> colleagues; //用于存储同事对象 //注册方法,用于增加同事对象 public void register(Colleague colleague) { colleagues.add(colleague); } //声明抽象的业务方法 public abstract void operation(); }
-
Concrete Mediator
:具体中介者角色实现中介者接口,包含各个同时角色的引用,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
class ConcreteMediator extends Mediator { //实现业务方法,封装同事之间的调用 public void operation() { ...... ((Colleague)(colleagues.get(0))).method1(); //通过中介者调用同事类的方法 ...... } }
-
Colleague
:抽象同事类角色定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能
abstract class Colleague { protected Mediator mediator; //维持一个抽象中介者的引用 public Colleague(Mediator mediator) { this.mediator=mediator; } public abstract void method1(); //声明自身方法,处理自己的行为 //定义依赖方法,与中介者进行通信 public void method2() { mediator.operation(); } }
-
Concrete Colleague
:具体同事类角色是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互
class ConcreteColleague extends Colleague { public ConcreteColleague(Mediator mediator) { super(mediator); } //实现自身方法 public void method1() { ...... } }
3、模式结构图
4、使用中介者模式改进案例
4.1、代码展示
-
抽象中介者类:这里是报亭的父类,没有使用抽象类和接口,通知观察者的方法也在此类实现
public interface Mediator { /** * 客户注册 * @param member 会员 * @return void **/ void register(Customer member); /** * 转发客户发的消息到其余客户 * @param from 发信息的客户 * @param msg 具体消息 * @return void **/ void relay(String from, String msg); }
-
房产中介者类
public class EstateMediator implements Mediator { /** * 注册在该房产公司的客户(包括卖方和买方) */ private List<Customer> members = new ArrayList<>(); @Override public void register(Customer member) { members.add(member); member.setMediator(this); } @Override public void relay(String from, String msg) { //通知到其余客户 for (Customer member : members) { if (!member.getName().equals(from)) { System.out.println("中介小哥传递" + from + "发送的消息[" + msg + "]给" + member.getName()); } } } }
-
抽象客户类
public abstract class Customer { /** * 中介者 */ protected Mediator mediator; /** * 客户姓名 */ private String name; public String getName() { return name; } public Customer(String name) { this.name = name; } public void setMediator(Mediator mediator) { this.mediator = mediator; } /** * 发送消息 * @param msg 消息内容 * @return void **/ public abstract void send(String msg); }
-
具体客户类
-
卖方
public class Seller extends Customer { public Seller(String name) { super(name); } @Override public void send(String msg) { mediator.relay(getName(), msg); } }
-
买方
public class Buyer extends Customer { public Buyer(String name) { super(name); } @Override public void send(String msg) { mediator.relay(getName(), msg); } }
-
4.2、客户端测试
public static void main(String[] args) throws IOException {
//定义中介者
Mediator mediator = new EstateMediator();
//定义卖方和买方客户
Customer buyer = new Buyer("张三");
Customer seller = new Seller("李四");
//买方和卖方注册到中介公司中
mediator.register(buyer);
mediator.register(seller);
//卖方买方对话,中介者负责传递消息
seller.send("临近地铁的大三居开始出售了!");
buyer.send("多大面积啊?");
seller.send("三室一厅120多平。");
buyer.send("多少钱啊?");
seller.send("200万整。");
}
输出
中介小哥传递李四发送的消息[临近地铁的大三居开始出售了!]给张三
中介小哥传递张三发送的消息[多大面积啊?]给李四
中介小哥传递李四发送的消息[三室一厅120多平。]给张三
中介小哥传递张三发送的消息[多少钱啊?]给李四
中介小哥传递李四发送的消息[200万整。]给张三
5、优缺点
-
优点
- 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
- 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,我们可以独立的改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭原则”。
- 可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
-
缺点
- 在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护
6、使用场景
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
- 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类
本文地址:https://blog.csdn.net/weixin_41951205/article/details/109584801