中介者模式
中介者模式(Mediator)也称为调停者模式,是一种比较简单的模式。
1中介者模式的定义
中介者模式的英文原文:
Dfine an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects form referring to each other explicitly,and it lets you vary their interaction independently.
意思是:用一个中介对象封装一系列对象(同事)的交互,中接着使用个对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间交互。
中介者模式有4个角色:
- 抽象中介者(Mediator)角色:该角色定义出同事对象到中介者对象的统一接口,用于同事角色之间的通信。
- 具体中介者(Concrete Mediator)角色:该角色实现抽象中介者,它依赖于各个同事角色,并通过协调各同事角色实现协作。
- 抽象同事(Colleague)角色:该角色定义出中介者到同事对象的接口,同事对象只知道中介者而不知道其余的同事对象。
- 具体同事(Concrete Colleague)角色:该角色实现抽象同事类,每一个具体同事类都清楚自己在小范围内的行为,而不知道大范围内的目的。
中介者模式的类图
创建抽象中介者
Mediator.java
package com.eric.行为型模式_Part2.中介者模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 抽象中介者
* @CreateTime 2020-12-10 14:35:03
*/
public abstract class Mediator {
//中介者模式的业务逻辑方法
public abstract void colleagueChanged(Colleague colleague);
}
创建抽象同事类
Colleague.java
package com.eric.行为型模式_Part2.中介者模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 抽象同事类
* @CreateTime 2020-12-10 14:37:19
*/
public abstract class Colleague {
private Mediator mediator;
//构造函数
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
//抽象方法,
public abstract void action();
//业务方法,调用此方法改变对象的内部状态
public void change()
{
this.mediator.colleagueChanged(this);
}
}
创建Colleague的实现类
ConcreteColleague1.java
package com.eric.行为型模式_Part2.中介者模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 具体同事类
* @CreateTime 2020-12-10 14:43:54
*/
public class ConcreteMediator1 extends Colleague{
//构造函数
public ConcreteMediator1(Mediator mediator) {
super(mediator);
}
//具体行动的方法
@Override
public void action() {
System.out.println("同事1开始行动...");
}
}
ConcreteColleague2.java
package com.eric.行为型模式_Part2.中介者模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 具体同事类
* @CreateTime 2020-12-10 14:43:54
*/
public class ConcreteMediator2 extends Colleague{
//构造函数
public ConcreteMediator2(Mediator mediator) {
super(mediator);
}
//具体行动的方法
@Override
public void action() {
System.out.println("同事2开始行动...");
}
}
创建中介者的具体实现类
ConcreteMediator.java
package com.eric.行为型模式_Part2.中介者模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 具体中介者
* @CreateTime 2020-12-10 14:36:23
*/
public class ConcreteMediator extends Mediator {
private Colleague c1;
private Colleague c2;
//中介者模式的业务逻辑方法
@Override
public void colleagueChanged( Colleague colleague) {
c1.action();
c2.action();
}
//工厂方法创建同事对象
public void createConcreteMediator()
{
c1 = new ConcreteMediator1(this);
c2 = new ConcreteMediator2(this);
}
//获取同事对象
public Colleague getC1()
{
return c1;
}
public Colleague getC2()
{
return c2;
}
}
2中介者模式的应用
a.中介者模式的优缺点
中介者模式的优点
- 减少类之间的依赖将原有的一对一的依赖,,使得对象之间的关系更易维护和理解。
- 避免同事对象之间的过度耦合,同事类只依赖于中介者,使同事类更易被复用,中介者类和同事类可以相对独立地演化。
- 中介者模式将对象的行为和协作抽象化,将对象在小尺度的行为上与其他对象的相互作用分开处理。
中介者模式的缺点
- 中介者模式降低了同事对象的复杂性,但增加了中介者类的复杂性。
- 中介者类经常充满了各个具体同事类的关系协调代码,这种代码是不能复用的。
b.中介者模式的注意事项
中介者模式很简单,但是简单并不代表容易使用,并且很容易被误用、滥用。在面向对象编程中,对象之间必然会有依赖关系,如果某个类和其他类没有任何相互依赖的关系,拿着各类就是一个孤岛,在系统中就没有存在的必要。一个类依赖多个类的情况也是正常的,存在即合理,并不是只要有多个依赖关系就考虑使用中介者模式。
在下列几种情况下不适合使用中介者模式:
- 不应当对数据类和方法类使用。初级设计师常常会设计出这样一种系统,让一系列类只含有数据,另一些类只含有方法。例如,描述一个客户时,这些设计者首先设计出一个"客户数据"类,只含有客户数据;另外再设计一个类叫“管理类”,含有曹旭OA客户以及此客户购买公司产品、付账的方法。管理列自然会涉及其它类,注入产品数据类型、订单数据类型、付账数据类型、应付数据类型等。这不是一种好的设计方式,也不是中介者模式。
- 正确理解封装,封装首先是行为,以及行为所涉及的状态封装。行为与状态是不应该分割开的。中介者模式的用途是管理很多的对象的相互作用,以便使这些对象可以专注自身的行为。
3中介者模式的实例
使用中介者模式模拟婚姻中介所的工作过程。
创建抽象婚介所MarriageAgency.java
package com.eric.行为型模式_Part2.中介者模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 婚介中介所接口
* @CreateTime 2020-12-10 15:59:33
*/
public interface MarriageAgency {
//为person进行配对
void pair(Person person);
//注册会员
void register(Person person);
}
创建抽象的人
Person.java
package com.eric.行为型模式_Part2.中介者模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 人的抽象类
* @CreateTime 2020-12-10 16:01:01
*/
public abstract class Person {
String name ; //姓名
int age ; //年龄
Sex sex;//性别
int requestAge;//要求对象的年龄。对象只有这一个要求
MarriageAgency agency;//婚介所
public Person(String name,int age,Sex sex,int requestAge,MarriageAgency agency){
this.name = name;
this.age = age;
this.sex = sex;
this.requestAge = requestAge;
this.agency = agency;
agency.register(this);//注册会员
}
//寻找对象
public void findPartner(){
agency.pair(this);
}
}
enum Sex{
MALE,FEMALE;
}
创建人的实现类
Man.java
package com.eric.行为型模式_Part2.中介者模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 男顾客
* @CreateTime 2020-12-10 16:09:32
*/
public class Man extends Person {
public Man(String name, int age,int requestAge, MarriageAgency agency) {
super(name, age, Sex.MALE, requestAge, agency);
}
}
Woman.java
package com.eric.行为型模式_Part2.中介者模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 男顾客
* @CreateTime 2020-12-10 16:09:32
*/
public class Woman extends Person {
public Woman(String name, int age, int requestAge, MarriageAgency agency) {
super(name, age, Sex.FEMALE, requestAge, agency);
}
}
创建婚介所的具体实现类
package com.eric.行为型模式_Part2.中介者模式.例1;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eric
* @ProjectName my_design_23
* @description 婚介所的实现类
* @CreateTime 2020-12-10 16:07:54
*/
public class MarriageAgencyImpl implements MarriageAgency {
//男顾客
List<Man> men = new ArrayList<Man>();
//女顾客
List<Woman> women = new ArrayList<Woman>();
@Override
public void pair(Person person) {
if(person.sex == Sex.MALE){
for (Woman woman : women) {
if(woman.age == person.requestAge){
System.out.println(person.name+"和"+woman.name+"配对成功!");
return;
}
}
}else if(person.sex == Sex.FEMALE){
for (Man man : men) {
if(man.age == person.requestAge)
{
System.out.println(person.name+"和"+man.name+"配对成功!");
return;
}
}
}
System.out.println("没有为"+person.name+"找到合适的对象");
}
//注册会员
@Override
public void register(Person person) {
if(person.sex == Sex.MALE)
{
men.add((Man)person);
}
else if(person.sex == Sex.FEMALE)
{
women.add((Woman)person);
}
}
}
创建测试类
Test.java
package com.eric.行为型模式_Part2.中介者模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 测试
* @CreateTime 2020-12-10 16:20:35
*/
public class Test {
public static void main(String[] args) {
MarriageAgencyImpl agency = new MarriageAgencyImpl();
Person john = new Man("John", 20, 18, agency);
Person Mike = new Man("Mike", 27, 25, agency);
Person Mary = new Woman("Mary", 25, 27, agency);
Person Jane = new Woman("Jane", 20, 22, agency);
john.findPartner();
Mike.findPartner();
}
}
测试结果