【设计模式】中介者模式

  |   0 评论   |   89 浏览

简介

定义一个对象,该对象封装了一组对象的交互方式。随着业务的方法会有大量的类,逻辑和计算都分布在类之间,如果代码重构那么还会增加更多的类,如此程序会越来越复杂,越来越难维护,稍微改动一点代码就会影响其他功能。使用中介模式,对象之间的通信被封装在中介对象中。对象之间不再直接通信,而是通过中介进行通信。这减少了通信对象之间的依赖关系,从而减少了耦合,属于行为型。
中介模式几个角色描述:
Mediator:定义通信接口,主要是在Colleague对象之间进行交互 。
ConcreteMediator:Mediator接口的实现类,协调Colleague对象之间的通信,它知道所有的Colleagues对象以及它们之间的通信。
Colleague:定义通信的接口,通过Mediator与其他Colleague对象进行通信。
ConcreteColleague:Colleague接口的实现类,通过Mediator与其他Colleague对象进行通信。

适用场景

1、应该避免一组交互对象之间的紧密耦合。
2、应该可以独立地更改一组对象之间的交互。
3、系统中对象之间存在复杂的引用关系,产生相互依赖关系结构混乱且难以理解
4、交互的公共行为,如果需要改变行为则可以增加新的中介者类

优点

1、将一对多转化成了一对一,降低程序复杂度
2、类之间解耦

缺点

1、中介者过多,导致系统复杂

扩展

会结合观察者模式,来做通信。

代码示例

image.png
存储类

public class Storage<T> {
    T value;
    T getValue() {
        return value;
    }
    void setValue(Mediator<T> mediator, String storageName, T value) {
        this.value = value;
        mediator.notifyObservers(storageName);
    }
}

中介类,可以存储数据、获取数据,数据有修改会有通知。

public class Mediator<T> {
    private final HashMap<String, Storage<T>> storageMap = new HashMap<>();
    private final CopyOnWriteArrayList<Consumer<String>> observers = new CopyOnWriteArrayList<>();
    public void setValue(String storageName, T value) {
        Storage storage = storageMap.computeIfAbsent(storageName, name -> new Storage<>());
        storage.setValue(this, storageName, value);
    }
    public Optional<T> getValue(String storageName) {
        return Optional.ofNullable(storageMap.get(storageName)).map(Storage::getValue);
    }
    public void addObserver(String storageName, Runnable observer) {
        observers.add(eventName -> {
            if (eventName.equals(storageName)) {
                observer.run();
            }
        });
    }
    void notifyObservers(String eventName) {
        observers.forEach(observer -> observer.accept(eventName));
    }
}

测试类

public class MediatorTest {
    public static void main(String[] args) {
        Mediator<Integer> mediator = new Mediator<>();
        mediator.setValue("bob", 20);
        mediator.setValue("alice", 24);
        mediator.getValue("alice").ifPresent(age -> System.out.println("age for alice: " + age));

        mediator.addObserver("bob", () -> {
            System.out.println("new age for bob: " + mediator.getValue("bob").orElseThrow(RuntimeException::new));
        });
        mediator.setValue("bob", 21);
    }
}

上面示例源码

源码分析

jdk中应用

Timer
image.png

也可以关注我的公众号:程序之声
图片
关注公众号,领取更多资源

本文为博主原创文章,未经博主允许不得转载。

评论

发表评论