【设计模式】中介者模式和观察者模式

中介者模式

中介模式的英⽂翻译是 Mediator Design Pattern。
在 GoF 中的《设计模式》⼀书中,它是这样定义的:

Mediator pattern defines a separate (mediator) object that encapsulates the interaction between a set of objects and the objects delegate their interaction to a mediator object instead of interacting with each other directly.

中介模式定义了⼀个单独的(中介)对象,来封装⼀组对象之间的交互。将这组对象之间的交互委派给中介对象,来避免对象之间的直接交互。属于行为型模式

通过引⼊中介这个中间层,将⼀组对象之间的交互关系(或者说依赖关系)从多对多(⽹状关系)转换为⼀对多(星状关系)

下图右边的交互图是利⽤中介模式对左边交互关系优化之后的结果,从图中我们可以很直观地看出,右边的交互关系更加清晰、简洁。
在这里插入图片描述
生活中有一个经典的中介者模式的例子,那就是航空管制。
为了让⻜机在⻜⾏的时候互不⼲扰,每架⻜机都需要知道其他⻜机每时每刻的位置,这就需要时刻跟其他⻜机通信。⻜机通信形成的通信⽹络就会⽆⽐复杂。这个时候,我们通过引⼊“塔台”这样⼀个中介,让每架⻜机只跟塔台来通信,发送⾃⼰的位置给塔台,由塔台来负责每架⻜机的航线调度。这样就⼤⼤简化了通信⽹络

我们的注册中心也是中介者模式在技术中的典型应用场景,生活中的朋友圈,QQ群, 淘宝商城都是中介者模式的应用

中介者模式主要有四个角色:
Mediator: 抽象中介者
ConcreteMediator: 具体中介者
Colleague: 抽象同事类
ConcreteColleague: 具体同事类

在一些简单场景下,可以不设计抽象中介者和抽象同事类,具体看你的使用场景

代码示例

我们用代码实现下QQ群的场景,每个QQ号都可以在群里发送内容,QQ群就承担着一个中介者的作用

public class QQ {
    
    

    private String name;

    public void setName(String name) {
    
    
        this.name = name;
    }

    public QQ(String name) {
    
    
        this.name = name;
    }

    public void sendMessage(QQGroup qqGroup, String message) {
    
    
        if (qqGroup.getMembers().contains(this)) {
    
    
            System.out.println("[" + this.name + "]:" + message + "in qq group " + qqGroup.getName());
        } else {
    
    
            System.err.println("你不在群里,不能说话");
        }
    }
}

public class QQGroup {
    
    
    private List<QQ> members;
    private String name;

    public List<QQ> getMembers() {
    
    
        return members;
    }

    public void addMember(QQ qq) {
    
    
        if (members == null) {
    
    
            members = new ArrayList<>();
        }
        members.add(qq);
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }
}

public class Test {
    
    

    public static void main(String[] args) {
    
    
        QQ member1 = new QQ("小明");
        QQ member2 = new QQ("小一");
        QQ member3 = new QQ("小花");
        QQGroup group = new QQGroup();
        group.setName("私人聊天群");
        group.addMember(member1);
        group.addMember(member2);
        member1.sendMessage(group, "明天我们去逛街");
        member2.sendMessage(group, "好啊");
        member3.sendMessage(group, "我也去");

    }

}

在这里插入图片描述

观察者模式

观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。
在 GoF 的《设计模式》⼀书中,它的定义是这样的:

扫描二维码关注公众号,回复: 14781885 查看本文章

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

在对象之间定义⼀个⼀对多的依赖,当⼀个对象状态改变的时候,所有依赖的对象都会⾃动收到通知。属于行为型模式。

⼀般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。不过,在实际的项⽬开发中,这两种对象的称呼是⽐较灵活的,有各种不同的叫法,⽐如:Subject-Observer、Publisher-Subscriber、Producer-Consumer、EventEmitter-EventListener、Dispatcher-Listener等。

观察者模式主要包含4种角色
抽象被观察者(Subject):被观察的对象,被观察者提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
具体被观察者
:在被观察者内部状态改变时,给所有注册过的观察者发出通知。
抽象观察者:为所有具体的观察者定义一个响应通知的接口
具体观察者:实现抽象观察者角色所要求的更新接口

代码示例

public class MyObservable {
    
    

    List<MyObserver> observerList;

    public void addObserver(MyObserver observer) {
    
    
        if (observerList == null) {
    
    
            observerList = new ArrayList<>();
        }
        observerList.add(observer);
    }

    public void notifyAllObserver(Object arg) {
    
    
        if (observerList == null) {
    
    
            return;
        }
        for (MyObserver observer : observerList) {
    
    
            observer.update(this, arg);
        }
    }

}

public class OrderCompleted extends MyObservable {
    
    

    private Long orderId;

    public OrderCompleted(Long orderId) {
    
    
        this.orderId = orderId;
    }

    public void notifyObservers() {
    
    
        //如果是使用的jdk自带的Observable类,要先设置changed标识,后续才可以发送成功
        super.notifyAllObserver(orderId);
    }
}

public interface MyObserver {
    
    

    void update(MyObservable observable, Object arg);
}

public class SmsNotification implements MyObserver {
    
    

    @Override
    public void update(MyObservable o, Object arg) {
    
    
        Long orderId = (Long) arg;
        System.out.println("您已下单成功,订单号为:" + orderId);
    }
}

public class EmailNotification implements MyObserver {
    
    

    @Override
    public void update(MyObservable o, Object arg) {
    
    
        Long orderId = (Long) arg;
        System.out.println("您已下单成功,升级为白金用户,订单号为:" + orderId);
    }
}

public class Test {
    
    
    
    public static void main(String[] args) {
    
    
        OrderCompleted orderCompleted = new OrderCompleted(9888121L);
        SmsNotification sms = new SmsNotification();
        EmailNotification email = new EmailNotification();
        orderCompleted.addObserver(sms);
        orderCompleted.addObserver(email);
        orderCompleted.notifyObservers();
    }
}

在这里插入图片描述

中介者模式和观察者模式对比

观察者模式和中介模式都是为了实现参与者之间的解耦,简化交互关系。
两者的不同在于应⽤场景上。在观察者模式的应⽤场景中,参与者之间的交互⽐较有条理,⼀般都是单向的,⼀个参与者只有⼀个⾝份,要么是观察者,要么是被观察者。
⽽在中介模式的应⽤场景中,参与者之间的交互关系错综复杂,既可以是消息的发送者、也可以同时是消息的接收者。

中介者模式和代理模式对比:
代理模式重点在代理,会对原对象做功能增强;但是中介者模式就是一个转发的作用,实际的工作还是要你自己去完成

猜你喜欢

转载自blog.csdn.net/qq_35448165/article/details/129465010