欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式详解—中介者模式

程序员文章站 2022-03-03 09:49:23
一、场景问题设计一套买房与卖房的交互程序。二、传统解决方案最直观的做法是定义卖方和买方的实体,二者直接进行信息交互。但是随着买方和卖方的人数新增,实体之间的交互会变得错综复杂,直接交互的设计方案会导致系统的通信链路交错复杂,且实体之间耦合过多,维护困难。因此我们可以采用中间层(中介)的方式来简化交互流程。即每个客户都只与中介交互,由中介来负责传递消息,使得各个实体间解耦,较少交互上的不便性。(即现在的房地产中介公司,当然缺点就是增加了中介费)。三、模式剖析1、模式定义中介者模式(Mediato...

一、场景问题

设计一套买房与卖房的交互程序。

二、传统解决方案

最直观的做法是定义卖方和买方的实体,二者直接进行信息交互。但是随着买方和卖方的人数新增,实体之间的交互会变得错综复杂,直接交互的设计方案会导致系统的通信链路交错复杂,且实体之间耦合过多维护困难。因此我们可以采用中间层(中介)的方式来简化交互流程。即每个客户都只与中介交互,由中介来负责传递消息,使得各个实体间解耦,较少交互上的不便性。(即现在的房地产中介公司,当然缺点就是增加了中介费)。

三、模式剖析

1、模式定义

中介者模式(Mediator Pattern):定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。

2、模式结构

中介者模式一般包含如下角色

  • Mediator抽象中介者角色

    它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法

    abstract class Mediator {
        protected ArrayList<Colleague> colleagues; //用于存储同事对象
    
        //注册方法,用于增加同事对象
        public void register(Colleague colleague) {
            colleagues.add(colleague);
        }
    
        //声明抽象的业务方法
        public abstract void operation();
    }
    
  • Concrete Mediator具体中介者角色

    实现中介者接口,包含各个同时角色的引用,协调各个同事角色之间的交互关系,因此它依赖于同事角色

    class ConcreteMediator extends Mediator {
        //实现业务方法,封装同事之间的调用
        public void operation() {
            ......
            ((Colleague)(colleagues.get(0))).method1(); //通过中介者调用同事类的方法
            ......
        }
    }
    
  • Colleague抽象同事类角色

    定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能

    abstract class Colleague {
        protected Mediator mediator; //维持一个抽象中介者的引用
    
        public Colleague(Mediator mediator) {
            this.mediator=mediator;
        }
    
        public abstract void method1(); //声明自身方法,处理自己的行为
    
        //定义依赖方法,与中介者进行通信
        public void method2() {
            mediator.operation();
        }
    }
    
  • Concrete Colleague具体同事类角色

    是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互

    class ConcreteColleague extends Colleague {
        public ConcreteColleague(Mediator mediator) {
            super(mediator);
        }
    
        //实现自身方法
        public void method1() {
            ......
        }
    }
    

3、模式结构图

设计模式详解—中介者模式

4、使用中介者模式改进案例

4.1、代码展示

  • 抽象中介者类:这里是报亭的父类,没有使用抽象类和接口,通知观察者的方法也在此类实现

    public interface Mediator {
    
        /**
         * 客户注册
         * @param member 会员
         * @return void
         **/
        void register(Customer member);
    
        /**
         * 转发客户发的消息到其余客户
         * @param from 发信息的客户
         * @param msg  具体消息
         * @return void
         **/
        void relay(String from, String msg);
    }
    
  • 房产中介者类

    public class EstateMediator implements Mediator {
    
        /**
         * 注册在该房产公司的客户(包括卖方和买方)
         */
        private List<Customer> members = new ArrayList<>();
    
        @Override
        public void register(Customer member) {
            members.add(member);
            member.setMediator(this);
        }
    
        @Override
        public void relay(String from, String msg) {
            //通知到其余客户
            for (Customer member : members) {
                if (!member.getName().equals(from)) {
                    System.out.println("中介小哥传递" + from + "发送的消息[" + msg + "]给" + member.getName());
                }
            }
        }
    }
    
  • 抽象客户类

    public abstract class Customer {
    
        /**
         * 中介者
         */
        protected Mediator mediator;
        /**
         * 客户姓名
         */
        private String name;
    
    
        public String getName() {
            return name;
        }
    
        public Customer(String name) {
            this.name = name;
        }
    
        public void setMediator(Mediator mediator) {
            this.mediator = mediator;
        }
    
        /**
         * 发送消息
         * @param msg 消息内容
         * @return void
         **/
        public abstract void send(String msg);
    }
    
  • 具体客户类

    • 卖方

      public class Seller extends Customer {
      
          public Seller(String name) {
              super(name);
          }
      
          @Override
          public void send(String msg) {
      
              mediator.relay(getName(), msg);
          }
      }
      
    • 买方

      public class Buyer extends Customer {
      
          public Buyer(String name) {
              super(name);
          }
      
          @Override
          public void send(String msg) {
              mediator.relay(getName(), msg);
          }
      }
      

4.2、客户端测试

public static void main(String[] args) throws IOException {
    //定义中介者
    Mediator mediator = new EstateMediator();

    //定义卖方和买方客户
    Customer buyer = new Buyer("张三");
    Customer seller = new Seller("李四");

    //买方和卖方注册到中介公司中
    mediator.register(buyer);
    mediator.register(seller);

    //卖方买方对话,中介者负责传递消息
    seller.send("临近地铁的大三居开始出售了!");
    buyer.send("多大面积啊?");
    seller.send("三室一厅120多平。");
    buyer.send("多少钱啊?");
    seller.send("200万整。");
}

输出

中介小哥传递李四发送的消息[临近地铁的大三居开始出售了!]给张三
中介小哥传递张三发送的消息[多大面积啊?]给李四
中介小哥传递李四发送的消息[三室一厅120多平。]给张三
中介小哥传递张三发送的消息[多少钱啊?]给李四
中介小哥传递李四发送的消息[200万整。]给张三

5、优缺点

  • 优点
    • 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
    • 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,我们可以独立的改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭原则”。
    • 可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
  • 缺点
    • 在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护

6、使用场景

  • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
  • 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象
  • 通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类

本文地址:https://blog.csdn.net/weixin_41951205/article/details/109584801