• 设计模式之中介者模式


    中介者模式

    概述

    中介者模式(Mediator)又称为调解者模式或调停者模式,中介者是一中行为型模式,听名字大家应该都知道了起到了中间桥梁的作用,
    在软件开发过程中,势必会碰到这样一种情况,多个类或多个子系统相互交互,而且交互很繁琐,导致每个类都必须知道他需要交互的类,这样它们的耦合会显得异常厉害。
    如果有这么一个中间者能够和所有的子系统交互,就会变得清晰的多.中介者模式就起到了这个作用.

    定义

    中介者包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用.从而使他们可以松散耦合.当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的相互作用,
    保证这些作用可以彼此独立的变化.中介者模式将多对多的相互作用转化为一对多的相互作用,终结者模式将对象的行为和协作抽象化.把对象在小尺度的行为上与其他对象的相互作用分开处理

    UML

    • Mediator : 抽象中介者角色,定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信.
    • ConcreteMediator : 具体中介者角色,继承于抽象中介者.实现抽象中介者中定义的事件方法,从一个同事类接收消息,然后通过消息影响其他同时类
    • Colleague : 抽象同事类角色,定义了中介者对象的接口,只知道中介者而而不知道其他同事类对象.
    • ConcreteColleague : 具体同事类角色,继承于抽象同事类,只知道本身在小范围内的行为,不知道其在大范围内的目的.

    使用场景

    • 对象间的交互操作很多且每个对象的行为操作都依赖彼此,导致依赖关系结构混乱时.
    • 向通过一个中间类来封装多个类中的行为,而又不行生成太多的子类

    例子

    中介者模式的例子很多,如一个网络聊天室

    • 首先定义Mediator对象
    package com.dyleaf.behavior.MediatorPattern;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public abstract class Mediator {
    
        protected List<User> userList;
        public Mediator() {
            userList = new ArrayList<User>();
        }
        public void addUser(User user){
            user.setMediator(this);
            this.userList.add(user);
        }
    
        public abstract void operation(User user, String msg);
    }
    
    • 定义Colleague对象
    package com.dyleaf.behavior.MediatorPattern;
    
    public abstract class User {
        protected Mediator mediator;
    
        protected String name;
    
        public User(String name) {
            this.name = name;
        }
    
        protected void setMediator(Mediator mediator){
            this.mediator = mediator;
        }
        protected abstract void sendMessage(String msg);
    
        protected abstract void getMessage(String msg);
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    
    • 具体的Colleague对象
    //vip
    
    public class VIPUser extends User{
        public VIPUser(String name) {
            super(name);
        }
    
        @Override
        protected void sendMessage(String msg) {
            this.mediator.operation(this, msg);
        }
    
        @Override
        protected void getMessage(String msg) {
            System.out.println(this.getName() + " get msg:"+msg);
        }
    
    }
    
    //common
    public class CommonUser extends User{
    
        public CommonUser(String name) {
            super(name);
        }
        @Override
        protected void sendMessage(String msg) {
            this.mediator.operation(this, msg);
        }
    
        @Override
        protected void getMessage(String msg) {
            System.out.println(this.getName() +  " get msg:"+msg);
        }
    
    }
    
    • 具体的mediator对象
    package com.dyleaf.behavior.MediatorPattern;
    
    public class ChatRoomMediator extends Mediator {
    
        @Override
        public void operation(User user, String msg) {
            System.out.println(user.getName() + "send a msg : " + msg);
            for(User userTmp : this.userList){
                userTmp.getMessage(msg);
            }
        }
    }
    
    • 客户端调用
    package com.dyleaf.behavior.MediatorPattern;
    
    public class Test {
        public static void main(String[] args) {
            CommonUser user1 = new CommonUser("小王");
            CommonUser user2 = new CommonUser("小陈");
            VIPUser vipUser = new VIPUser("小张");
    
            Mediator chatRoom = new ChatRoomMediator();
            chatRoom.addUser(user1);
            chatRoom.addUser(user2);
            chatRoom.addUser(vipUser);
    
            user2.sendMessage("hello everybody~");
        }
    }
    
    

    优缺点

    优点:

    • 避免同事类之间的过度耦合,使得各同事类之间可以相互独立的使用
    • 可以将对象间一对多的关联转变为一对一的关联,便于维护
    • 将对象的行为和协作进行抽象,能够比较灵活的处理对象之间相互作用.

    缺点:

    • 若果几个类间的依赖关系不复杂,使用中介者模式反而会使逻辑结构变得复杂.
    • 由于中介者封装了系统中对象间的相互关系,导致中介者会变得复杂.

    see source code

  • 相关阅读:
    swift 如何给tabBarItem的相关设计
    本地缓存
    Xcode7.2 导入XMPP框架错误解决
    Selenium WebUI自动化测试--PO中传递driver
    【转发】自动化测试中 数据源获取方式
    IntelliJ IDEA 开发环境设置
    Jmeter在csv传参时 请求参数乱码
    XAMPP phpmind Agileone 环境搭建及遇到问题的解决方法
    python浅拷贝和深拷贝
    一套简单的git版本控制代码
  • 原文地址:https://www.cnblogs.com/Dyleaf/p/8507065.html
Copyright © 2020-2023  润新知