设计模式

观察者模式-Observer

2020-04-05  本文已影响0人  花雨归来

1. 说明

当目标对象(被观察者)的状态发生变化时,自动通知观察它的对象。观察者模式常用于消息、事件驱动等。

实现步骤:

2. 示例

观察者接口:

public interface Observer {
    void update(SubJect subJect);
}

被观察者抽象对象:

public abstract class SubJect {
    // 用来保存注册的观察者对象
    private List<Observer> observers = new ArrayList<>();

    // 观察者注册(订阅)
    public void subscribe(Observer observer) {
        observers.add(observer);
    }

    // 删除(取消订阅)
    public void unsubscribe(Observer observer) {
        observers.remove(observer);
    }

    /**
     * 通知所有观察者
     */
    protected void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this);
        }
    }
}

实际的观察者:

public class ConcreteObserver implements Observer {
    private String name;

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

    @Override
    public void update(SubJect subJect) {
        System.out.println("我是观察者:" + name + ",我观察到了对象状态变成了:" + ((ConcreteSubject)subJect).getSubjectState() );
    }
}

实际的被观察者:

public class ConcreteSubject extends SubJect {
    // 目标对象的状态
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    /**
     * 状态变化时,通知观察者
     */
    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        this.notifyObservers();
    }
}

测试类:

public class ObserverTest {
    public static void main(String[] args) {
        // 创建目标(主题)
        ConcreteSubject subject = new ConcreteSubject();

        // 创建观察者
        ConcreteObserver concreteObserver = new ConcreteObserver("aaa");
        ConcreteObserver concreteObserver2 = new ConcreteObserver("bbb");
        ConcreteObserver concreteObserver3 = new ConcreteObserver("ccc");

        // 注册观察者
        subject.subscribe(concreteObserver);
        subject.subscribe(concreteObserver2);
        subject.subscribe(concreteObserver3);

        // 目标发生变化
        subject.setSubjectState("哈哈");

        // 取消订阅
        subject.unsubscribe(concreteObserver2);

        // 目标再次变化时,已取消订阅的观察者不再接收消息
        subject.setSubjectState("嘿嘿");
    }
}

测试结果:

我是观察者:aaa,我观察到了对象状态变成了:哈哈
我是观察者:bbb,我观察到了对象状态变成了:哈哈
我是观察者:ccc,我观察到了对象状态变成了:哈哈
我是观察者:aaa,我观察到了对象状态变成了:嘿嘿
我是观察者:ccc,我观察到了对象状态变成了:嘿嘿

3. 总结

注意观察者接口的参数,并不是必须的,具体取决于应用场景,观察者接口方法最重要的作用是提供一个事件通知的入口,如在NettyChannelInboundHandler中,提供的channelRegisteredchannelReadchannelReadComplete等,其作用就类似于本文中的update方法。

上一篇 下一篇

猜你喜欢

热点阅读