中介者模式的定义
用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
中介者模式的优点
- 适当地使用中介者模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。
- 使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。
- 使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
适用场景
在面向对象编程中,一个类必然会与其他的类发生依赖关系,完全独立的类是没有意义的。一个类同时依赖多个类的情况也相当普遍,既然存在这样的情况,说明,一对多的依赖关系有它的合理性,适当的使用中介者模式可以使原本凌乱的对象关系清晰,但是如果滥用,则可能会带来反的效果。一般来说,只有对于那种同事类之间是网状结构的关系,才会考虑使用中介者模式。可以将网状结构变为星状结构,使同事类之间的关系变的清晰一些。
中介者模式是一种比较常用的模式,也是一种比较容易被滥用的模式。对于大多数的情况,同事类之间的关系不会复杂到混乱不堪的网状结构,因此,大多数情况下,将对象间的依赖关系封装的同事类内部就可以的,没有必要非引入中介者模式。滥用中介者模式,只会让事情变的更复杂。
参与者
1、Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
2、ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
3、Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
4、ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。
/** * 抽象中介者类 * @author [email protected] * */ public abstract class Mediator { // 用于添加储存 "房东"角色 protected List<Person> landlordList = new ArrayList<Person>(); // 用于添加储存 "求租者"角色 protected List<Person> renterList = new ArrayList<Person>(); /** * 中介者注册房东信息 * @param landlord 房东实体 */ public void registerLandlord(Person landlord){ landlordList.add(landlord); } /** * 中介者注册 求租者信息 * @param landlord 房东实体 */ public void registerRenter(Person landlord){ renterList.add(landlord); } /** * 声明抽象方法 由具体中介者子类实现 消息的中转和协调 */ public abstract void operation(Person person, String message); }
/** * 抽象同事类: * @author [email protected] * */ public abstract class Person { // 维持一个抽象中介者的引用 protected Mediator mediator; protected String name; public Person(String name, Mediator mediator){ this.mediator = mediator; this.name = name; } /** * 设置中介者对象 * @param mediator */ public void setMediator(Mediator mediator){ this.mediator = mediator; } /** * 向中介 发送消息 */ protected abstract void sendMessage(String msg); /** * 从中介 获取消息 */ protected abstract void getMessage(String msg); }
/** * 具体同事类:这里的角色是 房东 * @author [email protected] * */ public class Landlord extends Person { public Landlord(String name, Mediator mediator) { super(name,mediator); } @Override protected void sendMessage(String msg) { mediator.operation(this, msg); } @Override protected void getMessage(String msg) { System.out.println("房东["+ name +"]收到中介发来的消息:" + msg); } }
/** * 具体同事类:这里的角色是 租房者 * @author [email protected] * */ public class Renter extends Person { public Renter(String name, Mediator mediator) { super(name, mediator); } @Override protected void sendMessage(String msg) { mediator.operation(this, msg); } @Override protected void getMessage(String msg) { System.out.println("求租者[" + name + "]收到中介发来的消息: " + msg); } }
/** * Created with IntelliJ IDEA. * User:by gyw * Date:2018-04-26 10:04 */ /** * 具体中介者类:这里的角色是 房屋出租中介 * @author [email protected] * */ public class HouseMediator extends Mediator { @Override public void operation(Person person, String message) { if(person instanceof Renter){ // 将租屋的需求消息传递给 注册了的房东们 for(Person landlord: landlordList){ landlord.getMessage(message); } } else if(person instanceof Landlord){ // 将房东的出租房消息传递给 注册了的 房屋求租者们 for(Person renter : renterList){ renter.getMessage(message); } } } }
/** * 客户端测试类 * @author [email protected] * */ public class Client { public static void main(String[] args) { // 实例化房屋中介 Mediator mediator = new HouseMediator(); Person landlordA, landlordB, renter; landlordA = new Landlord("房东1", mediator); landlordB = new Landlord("房东2", mediator); renter = new Renter("小小",mediator); // 房东注册中介 mediator.registerLandlord(landlordA); mediator.registerLandlord(landlordB); // 求租者注册中介 mediator.registerRenter(renter); // 求租者 发送求租消息 renter.sendMessage("在南环附近租套房子,价格1000元左右一个月"); System.out.println("--------------------------"); // 房东A 发送房屋出租消息 landlordA.sendMessage("南环附近有一房一厅出租 1200/月 光线好 近公交站"); } }
房东[房东1]收到中介发来的消息:在南环附近租套房子,价格1000元左右一个月
房东[房东2]收到中介发来的消息:在南环附近租套房子,价格1000元左右一个月
--------------------------
求租者[小小]收到中介发来的消息: 南环附近有一房一厅出租 1200/月 光线好 近公交站