设计模式——观察者模式

290 阅读3分钟
什么是观察者模式?

观察者模式属于对象的行为模式。其用意是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

举个例子?

举个例子

公众号发布新文章的时候,用户A、B、C会接到通知并且自动更新。公众号称为“主题”或者“观察目标”,用户A、B、C通过“关注”(动作)成为“观察者”。一个观察目标可以对应多个观察者,观察者彼此之间没有相互联系,可以根据需要随意关注或取关公众号。换句话说,公众号很容易刷关注量(扩展)。

1)写个抽象观察者

// 一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用
public abstract class Observer {

    protected Subject subject;

    public abstract void update();
}

2)写个抽象主题(抽象目标类)

// 提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法
public class Subject {

    private List<Observer> observers = new ArrayList<>();

    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyAllObservers();
    }

    public void attach(Observer observer){
        observers.add(observer);
    }

    public void notifyAllObservers(){
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

3)写3个观察者

// 实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态
public class ConcreteObserverA extends Observer{

    public ConcreteObserverA(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.err.println("用户A:" + subject.getState());
    }
}
// 实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态
public class ConcreteObserverB extends Observer{

    public ConcreteObserverB(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.err.println("用户B:" + subject.getState());
    }
}
// 实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态
public class ConcreteObserverC extends Observer{

    public ConcreteObserverC(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.err.println("用户C:" + subject.getState());
    }
}

4)使用

public static void main(String[] args) {
    Subject subject = new Subject();
    new ConcreteObserverA(subject);
    new ConcreteObserverB(subject);
    new ConcreteObserverC(subject);
    System.err.println("第一篇发布编号:" + 1);
    subject.setState(1);
    System.err.println("第二个发布编号:" + 2);
    subject.setState(2);
}

5)控制台输出结果

控制台输出结果

总结

观察模式涉及三个角色: 抽象主题(Subject)角色 :也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法; 具体主题(Concrete Subject)角色 :也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象; 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用;具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。