设计模式之中介者模式

一、什么是中介者模式

中介者模式,用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式又叫调停模式,属于行为型设计模式,是迪米特法则的典型应用。

设计模式之中介者模式插图
由凌乱的网状结构转变为清晰的星型结构

二、中介者模式类图

设计模式之中介者模式插图2

三、中介者模式角色

  • 抽象中介者角色(Mediator):抽象中介者角色定义统一的接口,以及一个或者多个事件方法,用于各同事角色之间的通信。
  • 具体中介者角色(ConcreteMediator):实现了抽象中介者所声明的事件方法,协调各同事类之间的行为,持有所有同事类对象的引用。
  • 抽象同事类角色(Colleague):定义了抽象同事类,持有抽象中介者对象的引用。
  • 具体同事类角色(ConcreteColleague):继承抽象同事类,实现自己业务,通过中介者跟其他同事类进行通信。

四、中介者模式优缺点

优点:

  1. 通过将对象彼此解耦,可以增加对象的复用性。
  2. 通过将控制逻辑集中,可以简化系统维护。
  3. 可以让对象之间所传递的消息变得简单而且大幅减少。
  4. 提高系统的灵活性,使得系统易于扩展和维护。

缺点:

  1. 中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响。
  2. 如果设计不当,中介者对象本身变得过于复杂,不易维护和管理。

五、中介者模式demo示例

1、Demo需求

使用中介者模式:设定公司总经理为中介者角色,公司各部门为具体同事角色,部门工作分为内部工作和外部工作。

2、接口及抽象类定义

/**
  * 抽象中介者角色
  */ public interface Mediator {

     void register(String name, Department department);
 
     void command(String name);
 }
/**
  * 抽象同事角色
  */ public abstract class Department {

     // 中介者对象
     protected Mediator mediator;

     public Department(Mediator mediator) {
         this.mediator = mediator;
     }
 
     /**
      * 处理本部门内部事务
      */     public abstract void executeInsideThing();
 
     /**
      * 处理部门外的事务
      */     public abstract void executeOutsideThing();
 }

3、实现类定义

/**
  * 具体中介者角色:总经理
  */ public class PresidentMediator implements Mediator {
 
     private Map<String,Department> departmentMap = new HashMap<>();

     public void register(String name, Department department) {
         departmentMap.put(name,department);
     }
 
     public void command(String name) {
         departmentMap.get(name).executeInsideThing();
         departmentMap.get(name).executeOutsideThing();
     }
 }
/**
  * 具体同事角色:研发部类
  */ public class DevelopmentDepartment extends Department {
 
     public DevelopmentDepartment(Mediator mediator) {
         super(mediator);
         mediator.register("研发部",this);
     }
 
     @Override
     public void executeOutsideThing() {
         System.out.println("研发部:汇报工作!资源不够,需要找人!");
         mediator.command("财务部");
     }
 
     @Override
     public void executeInsideThing() {
         System.out.println("研发部:专心科研,研发项目!");
     }
 }
/**
  * 具体同事角色:财务部类
  */ public class FinancialDepartment extends Department {
 
     public FinancialDepartment(Mediator mediator) {
         super(mediator);
         mediator.register("财务部",this);
     }
 
     @Override
     public void executeInsideThing() {
         System.out.println("财务部内部事务:1.收账款;2.算利润;3.发奖金");
     }
 
     @Override
     public void executeOutsideThing() {
         System.out.println("财务部外部事务:提请总经理审批,搞投资理财,钱生钱。");
     }
 }
/**
  * 具体同事角色:市场部
  */ public class MarketDepartment extends Department {
 
     public MarketDepartment(Mediator mediator) {
         super(mediator);
         mediator.register("市场部",this);
     }
 
     @Override
     public void executeOutsideThing() {
         System.out.println("市场部:1.找客户! 2.申请资金,投广告!");
         mediator.command("财务部");
     }
 
     @Override
     public void executeInsideThing() {
         System.out.println("市场部:制定工作计划!挖掘潜在客户!");
     }
 }
/**
  * @Description: 具体同事角色:人事部门类
  **/ public class PersonnelDepartment extends Department {

     public PersonnelDepartment(Mediator mediator) {
         super(mediator);
         mediator.register("人事部",this);
     }
 
     @Override
     public void executeInsideThing() {
         System.out.println("人事部内部事务:1.招聘人才 2.组织公司活动");
     }
 
     @Override
     public void executeOutsideThing() {
         System.out.println("人事部外部事务:向总经理申请活动经费.");
         mediator.command("财务部");
     }
 }

4、测试

/**
  * 中介者模式客戶端测试类
  */ public class Client {

     public static void main(String[] args) {
         PresidentMediator president = new PresidentMediator();
         DevelopmentDepartment development = new DevelopmentDepartment(president);
         FinancialDepartment financial = new FinancialDepartment(president);
         MarketDepartment market = new MarketDepartment(president);
         PersonnelDepartment personnel = new PersonnelDepartment(president);
         // 研发部
         development.executeInsideThing();
         development.executeOutsideThing();
         System.out.println("=========================================================");
         // 财务部
         financial.executeInsideThing();
         financial.executeOutsideThing();
         System.out.println("=========================================================");
         // 市场部
         market.executeInsideThing();
         market.executeOutsideThing();
         System.out.println("=========================================================");
         // 行政部
         personnel.executeInsideThing();
         personnel.executeOutsideThing();
     }
 }

控制台日志:

研发部:专心科研,研发项目!
研发部:汇报工作!资源不够,需要找人!
财务部内部事务:1.收账款;2.算利润;3.发奖金
财务部外部事务:提请总经理审批,搞投资理财,钱生钱。
=========================================================
财务部内部事务:1.收账款;2.算利润;3.发奖金
财务部外部事务:提请总经理审批,搞投资理财,钱生钱。
=========================================================
市场部:制定工作计划!挖掘潜在客户!
市场部:1.找客户! 2.申请资金,投广告!
财务部内部事务:1.收账款;2.算利润;3.发奖金
财务部外部事务:提请总经理审批,搞投资理财,钱生钱。
=========================================================
人事部内部事务:1.招聘人才 2.组织公司活动
人事部外部事务:向总经理申请活动经费.
财务部内部事务:1.收账款;2.算利润;3.发奖金
财务部外部事务:提请总经理审批,搞投资理财,钱生钱。

发表评论