Java设计模式之中介者模式

中介者模式也叫作调停模式,是处理项目中网状结构的一种设计模式。中介者,顾名思义就是周旋在各方中间的协调者,它让系统的各个模块之间可以单独的运转。

定义

中介者模式是封装了一系列对象之间相互作用的方式,将对象之间的强耦合关系变成一种松散耦合关系。该模式将一种多对多的关系转变成一种以中介者为中心的一对多关系,从而使各个对象可以进行独立的自主变化。

场景

当系统中有多个对象相互作用时,修改一个对象会导致其他对象都发生变化。此时,可以引入中介者模式,将网状结构转换成星型结构,降低系统复杂性,提高扩展性。

角色

抽象中介者角色

中介者类的抽象,一般定义了其他模块对象到中介者对象的接口,多数为抽象类。

具体中介者

对抽象中介者的实现,它实现了抽象中介者的方法,定义了从其他模块对象接收消息以及发送消息的行为

其他模块的抽象

定义了中介者对象的接口,它只知道中介者的存在

其他模块的抽象具体实现

实现于其他模块的抽象,定义了自身的行为

说明

通过上面的描述,可能有些人发现了中介者和其他模块之间具备强耦合关系,事实上,的确如此,中介者模式借助于这种强耦合关系来降低其他模块之间的耦合程度。中介者担任一个消息传递的角色,从一个模块接收消息,然后通知其他模块进行自我改变。基于这种结构,中介者本身就不免会显得有些臃肿。

代码演示

中介者在现实生活中也很常见,比如房屋中介、汽车销售中介等等。我们就房屋中介这个场景来看下具体实现。这个场景下有三个角色,中介、买方、卖方。首先我们定义买卖方抽象。

/**
 * 抽象模块角色,持有一个中介者的引用
 */
public abstract class ICustomer {

  protected AbstractMediator mediator;

  public ICustomer(AbstractMediator mediator) {
    this.mediator = mediator;
  }

  public abstract String getName();
}

接下来实现卖方和买方

/**
 * 卖方
 */
public class Seller extends ICustomer {

  public Seller(AbstractMediator mediator) {
    super(mediator);
  }

  @Override public String getName() {
    return "卖方";
  }

  /**
   * 卖方行为
   */
  public void sell(double price) {
    System.out.println("卖家同意以" + price + "W的价格出售房屋");
  }

  public double getLowestPrice() {
    return 195.0D;
  }

  /**
   * 上架房源,通知中介者
   */
  public void upload() {
    System.out.println("卖家预以200.0W的价格出售房屋");
    mediator.coordinate(this);
  }
}
/**
 * 买家
 */
public class Purchaser extends ICustomer {

  private double offeredPrice = 190.0D;

  public Purchaser(AbstractMediator mediator) {
    super(mediator);
  }

  @Override public String getName() {
    return "买方";
  }

  public double getPrice() {
    return offeredPrice;
  }

  /**
   * 买家决定调价买入,让中介者告知卖方
   */
  public void buy() {
    offeredPrice = 195.0D;
    System.out.println(getName() + "调价到195.0W资金购买房屋");
    mediator.coordinate(this);
  }

  /**
   * 买家寻找房源的行为
   */
  public void search() {
    System.out.println(getName() + "准备190.0W资金购买房屋");
  }
}

然后看下中介者抽象以及实现

/**
 * 抽象中介者
 */
public abstract class AbstractMediator {

  /**
   * 接收消息的方法
   */
  public abstract void coordinate(ICustomer customer);
}
/**
 * 抽象者具体实现
 */
public class Mediator extends AbstractMediator {

  /**
   * 模块一实现
   */
  private Seller seller;
  /**
   * 模块二实现
   */
  private Purchaser purchaser;

  public void setSeller(Seller seller) {
    this.seller = seller;
  }

  public void setPurchaser(Purchaser purchaser) {
    this.purchaser = purchaser;
  }

  @Override public void coordinate(ICustomer customer) {
    // 如果是买方传递过来的消息,则通知买方
    if (customer == seller) {
      purchaser.search();
      purchaser.buy();
    } else if (customer == purchaser) {
      if (purchaser.getPrice() >= seller.getLowestPrice()) {
        seller.sell(purchaser.getPrice());
      } else {
        System.out.println("双方价格没有谈拢,终止交易");
      }
    }
  }
}

在一次买卖行为中,卖方会先上传房源到中介平台,中介平台查询适合的房屋通知买方,询价,最后通知卖方交易。在代码层面,首先要建立买卖双方和中介的星型结构

  public static void main(String[] args) {
    // 构建中介者模式星型结构
    Mediator mediator = new Mediator();
    Purchaser purchaser = new Purchaser(mediator);
    Seller seller = new Seller(mediator);
    mediator.setPurchaser(purchaser);
    mediator.setSeller(seller);
    // 准备卖房
    seller.upload();
  }

然后会触发一次交易流程

卖家预以200.0W的价格出售房屋
买方准备190.0W资金购买房屋
买方调价到195.0W资金购买房屋
卖家同意以195.0W的价格出售房屋

到此,交易结束,在这个交易流程中,买卖双方只知道中介者的存在,不知道彼此的存在,可以让买卖双方进行自主变化(调价),提高了系统的灵活性。需要注意的是,在中介者实现中,模块类型是实例类型,而非接口类型,违背了依赖倒置原则。当然了,这也是为了实现各个模块的自我变化的一种妥协。

关于源码

在安卓中,系统层的KeyguardViewMediator类就运用了中介者模式,它持有了几个管理类,也就是模块对象,各个模块通过KeyguardViewMediator来进行通信和协调工作

public class KeyguardViewMediator extends SystemUI {

    private AlarmManager mAlarmManager;
    private AudioManager mAudioManager;
    private StatusBarManager mStatusBarManager;
    ...
    
    private void adjustStatusBarLocked(boolean forceHideHomeRecentsButtons) {
        if (mStatusBarManager == null) {
            mStatusBarManager = (StatusBarManager)
                    mContext.getSystemService(Context.STATUS_BAR_SERVICE);
        }
        ...
        mStatusBarManager.disable(flags);
        ...
        }
    }
    
    
}

上图中适配锁屏时状态栏状态的方法就是由StatusBarManager具体实施的。

总结

中介者模式是针对复杂的网状结构进行解耦的设计,当一个系统内有很多对象彼此之间有交互,构成比较繁杂的网状结构,这个时候就应该考虑使用中介者模式来解耦合。当然了,如果只是几个对象之间的交互,并且没有构成复杂的网状体系,则没有要使用中介者模式了。总之,在使用一种设计模式时,需要权衡下利弊。

你可能感兴趣的:(Java设计模式之中介者模式)