17.中介者模式

中介者模式是一种设计模式,通过引入一个中介对象,协调多个对象间的交互,降低耦合度。本文详细介绍了中介者模式的角色、职责、优缺点及其实例,以婚姻中介为例展示了如何应用该模式。在示例中,中介者类负责处理男女会员的配对逻辑,实现了对象间的解耦。
摘要由CSDN通过智能技术生成

一、介绍

  • 中介者模式也叫调停者模式,是一种比较简单的模式
  • 用一个中介对象封装一系列对象(同事)的交互,中介者使各对象不需要显示的相互作用,从而使其耦合松散,而且可以独立的改变它们之间的交互。

二、原理类图

1

2.1 角色和职责

  1. 抽象中介者(Mediator)角色:该角色定义出同事对象到中介者对象的统一接口,用于各同事角色之间的通信。
  2. 具体中介者(Concrete Mediator)角色:该角色实现抽象中介者,它依赖于各个同事角色,并通过协调各同事角色实现协作行为。
  3. 抽象同事(Colleague)角色:该角色定义出中介者到同事对象的接口,同事对象只知道中介者而不知道其余的同事对象。
  4. 具体同事(Concrete Colleague)角色:该角色实现抽象同事类,每一个具体同事类都清楚自己在小范围内的行为,而不知道大范围内的目的。

2.2 代码分析

  1. 抽象中介者Mediator的代码如下所示。
    【代码 6-1】 Mediator.java
//抽象中介者
public abstract class Mediator {
    //中介者模式的业务逻辑方法
    public abstract void colleagueChanged(Colleague c);
}
  1. 具体中介者ConcreteMediator的代码如下所示。
    【代码 6-2】 ConcreteMediator.java
//具体中介者
public class ConcreteMediator extends Mediator {
    private ConcreteColleague1 c1;
    private ConcreteColleague2 c2;
    //中介者模式的业务逻辑方法
    public void colleagueChanged(Colleague c){
        c1.action();
        c2.action();
    }
    //工厂方法,创建同事对象
    public void createConcreteMediator(){
        c1=new ConcreteColleague1(this);
        c2=new ConcreteColleague2(this);
    }
    //获取同事对象
    public ConcreteColleague1 getC1() {
        return c1;
    }
    public ConcreteColleague2 getC2() {
        return c2;
    }
}
  1. 抽象同事Colleague的代码如下所示。
    【代码 6-3】 Colleague.java
//抽象同事类
 public abstract class Colleague {
     private Mediator mediator;
     //构造函数
     public Colleague(Mediator m){
         this.mediator =m;
     }
     //getter和setter方法
     public Mediator getMediator() {
         return mediator;
     }
     public void setMediator(Mediator mediator) {
         this.mediator = mediator;
     }
     //抽象行动方法,由子类实现
     public abstract void action();
     //业务方法,调用此方法改变对象的内部状态
     public void change(){
         this.mediator.colleagueChanged(this);
     }
 }
  1. 具体同事ConcreteColleague1和ConcreteColleague2的代码如下所示。
    【代码 6-4】 ConcreteMediator1.java
//具体同事类
public class ConcreteColleague1 extends Colleague{
    //构造函数
    public ConcreteColleague1(Mediator m)
    {
        super(m);
    }
    //实现具体行动方法
    public void action(){
        System.out.println("这是同事1的行动方法!");
    }
}
  1. 【代码 6-5】 ConcreteMediator2.java
public class ConcreteColleague2 extends Colleague{
    //构造函数
    public ConcreteColleague2(Mediator m)
    {
        super(m);
    }
    //实现具体行动方法
    public void action(){
        System.out.println("这是同事2的行动方法!");
    }
}

三、优缺点

3.1 优点:

  1. 减少类间的依赖,将原有的一对多的依赖变成一对一的依赖,使得对象之间的关系更易维护和理解。
  2. 避免同事对象之间过度耦合,同事类只依赖于中介者,使同事类更易被复用,中介类和同事类可以相对独立地演化。
  3. 中介者模式将对象的行为和协作抽象化,将对象在小尺度的行为上与其他对象的相互作用分开处理。

3.2 缺点:

  1. 中介者模式降低了同事对象的复杂性,但增加了中介者类的复杂性。
  2. 中介者类经常充满了各个具体同事类的关系协调代码,这种代码是不能复用的。

注意事项

1. 不应在责任划分混乱时使用;
2. 不应对数据类和方法类使用

四、实例

使用中介者模式模拟婚姻中介所的工作过程。类图如下所示:
1

  1. 婚姻中介所接口MarriageAgency代码如下所示。
    【描述6.D.1】 MarriageAgency.java
public interface MarriageAgency {

     void pair(Person person); // 为person配对
     void register(Person person); // 注册会员
 }
  1. 人的抽象类Person的代码如下所示。
    【描述6.D.1】 Person.java
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;
  }

上述代码中除了定义Person抽象类之外,还使用枚举类型Sex对人的性别进行区分。 婚姻中介所实现类MarriageAgencyImpl实现

  1. MarriageAgency接口,其代码如下所示。
    【描述6.D.1】 MarriageAgencyImpl.java
public class MarriageAgencyImpl implements MarriageAgency {
    List<Man> men = new ArrayList<Man>(); // 男会员
    List<Woman> women = new ArrayList<Woman>(); // 女会员
    @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);
    }
    @Override
    public void pair(Person person) {
        if (person.sex == Sex.MALE) {
            for (Woman w : women)
                if (w.age == person.requestAge) {
                    System.out.println(person.name + "和" + w.name + "配对成功");
                    return;
                }
        } else if (person.sex == Sex.FEMALE) {
            for (Man m : men)
                if (m.age == person.requestAge) {
                    System.out.println(person.name + "和" + m.name + "配对成功");
                    return;
                }
        }
        System.out.println("没有为" + person.name + "找到合适的对象");
    }
}

上述代码中 pair()方法用于对人进行配对。当传过来的参数对象 person 的性别是男时,则在女会员列表Women 中搜索要求对象的年龄与之匹配的女性,否则就在男会员列表Men中搜索男性。

  1. 男人类Man和女人类Woman都是Person的子类,代码分别如下所示。
    【描述6.D.1】 Man.java

public class Man extends Person {
    public Man(String name, int age, int requestAge, MarriageAgency agency) {
        super(name, age, Sex.MALE, requestAge, agency);
    }
}

【描述6.D.1】 Woman.java

public class Woman extends Person {
   public Woman(String name, int age, int requestAge, MarriageAgency agency) {
       super(name, age, Sex.FEMALE, requestAge, agency);
  1. 【描述6.D.1】 Test.java
public class Test {
    public static void main(String[] args) {
        MarriageAgency agency = new MarriageAgencyImpl();
        Person m1 = new Man("John", 20, 18, agency);
        Person m2 = new Man("Mike", 27, 25, agency);
        Person w1 = new Woman("Mary", 25, 27, agency);
        Person w2 = new Woman("Jane", 20, 22, agency);
        m1.findPartner();
        m2.findPartner();
    }
}
  1. 运行后结果如下。
没有为John找到合适的对象
MikeMary配对成功
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值