Java design patterns 2 - observer mode

Observer Pattern

definition

Establish dependencies between objects - many, so that, when an object's state changes, it's all dependent persons are notified and updated automatically.

Observer mode, when the observed object changes state, will notify all observers. Here there are two modes of PUSH and PULL. PUSH observation target is active on the content updates to the observer, and the observer is the PULL actively acquire an update to the observed object.

Observer pattern often appears in the Java GUI, Web, and Spring and other places.

UML 类图

In fact, Java's java.util package already contains some of the most basic things observer pattern design: Observable class and the Observer interface. But the Observer interface and Observable class after Java9 was annotated as Deprecated.

Observable class can be considered a "can be observed" in a class of things, which changed is a member variable of type boolean indicating whether this thing has changed, obs has maintained a list consisting of Vector observer. Plays an important role is setChanged () method and notifyObservers () method.

public void notifyObservers(Object arg) {

     //临时对象数组,存储观察者
    Object[] arrLocal;

    synchronized (this) {
        if (!changed)
            return;
        arrLocal = obs.toArray();
        //将changed设置为false
        clearChanged();
    }

    //逆序轮询通知观察者
    for (int i = arrLocal.length-1; i>=0; i--)
        ((Observer)arrLocal[i]).update(this, arg);
}

protected synchronized void setChanged() {
    changed = true;
}

member variable is changed to true to update the status notification to all observers. So every time you notice the observer status updates, call setChanged () method.

Observer interface is observed "may be observed" thing things, update method is used to update state. The first argument is the observation target, the second argument is the observation information object passed over.

Show

To Press (publisher) and subscribers (subscriber), to design a simple observation mode is achieved by the use of components · Java provides.

PUSH way to

Publisher.class

public class Publisher extends Observable {
    private ArrayList<String> books;

    Publisher(){
        books = new ArrayList<>();
    }

    public void addBook(String book){
        books.add(book);
        super.setChanged();
        super.notifyObservers(books);
    }
}

Subscriber.class

public class Subscriber implements Observer {

    private String name;

    Subscriber(String name){
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        if(arg instanceof ArrayList){
            ArrayList<String> books = (ArrayList<String>)arg;
            System.out.print(name+" ");
            books.stream().forEach(book -> System.out.print(book+" "));
            System.out.println();
        }
    }
}

Main.class

public class Main {
    public static void main(String[] args) {
        Publisher publisher = new Publisher();

        publisher.addObserver(new Subscriber("A"));
        publisher.addObserver(new Subscriber("B"));
        publisher.addObserver(new Subscriber("C"));

        System.out.println("Publisher出新书了!");
        publisher.addBook("数据结构");

        System.out.println("Publisher出新书了!");
        publisher.addBook("操作系统");

        System.out.println("Publisher出新书了!");
        publisher.addBook("模拟电路");

    }
}
Publisher出新书了!
C 数据结构
B 数据结构
A 数据结构
Publisher出新书了!
C 数据结构 操作系统
B 数据结构 操作系统
A 数据结构 操作系统
Publisher出新书了!
C 数据结构 操作系统 模拟电路
B 数据结构 操作系统 模拟电路
A 数据结构 操作系统 模拟电路

PULL way to

Publisher.class

public class Publisher extends Observable {

    //...代码不变,修改下面的

    public void addBook(String book){
        books.add(book);
        super.setChanged();
        super.notifyObservers();
    }

    public ArrayList<String> getBooks() {
        return books;
    }
}

Subscriber.class

public class Subscriber implements Observer {

    //...代码不变,修改下面的

    @Override
    public void update(Observable o, Object arg) {
        if(o instanceof Publisher){
            Publisher publisher = (Publisher)o;

            System.out.print(name+" ");
            publisher.getBooks().stream().forEach(book -> System.out.print(book+" "));
            System.out.println();
        }
    }
}

Main.class

Publisher出新书了!
C 数据结构
B 数据结构
A 数据结构
Publisher出新书了!
C 数据结构 操作系统
B 数据结构 操作系统
A 数据结构 操作系统
Publisher出新书了!
C 数据结构 操作系统 模拟电路
B 数据结构 操作系统 模拟电路
A 数据结构 操作系统 模拟电路

Shortcoming

  1. Java provides Observable class poll to subscribers of the fixed order, and after the first subscription received. This increases the degree of coupling between the two, after all, the purpose of this model is designed to reduce the coupling between interacting objects.
for (int i = arrLocal.length-1; i>=0; i--)
    ((Observer)arrLocal[i]).update(this, arg);
  1. Observable is a class and not an interface. Because Java does not have multiple inheritance, thus limiting the scalability and weakened the publisher of the code reusability.

  2. Observable class the two most important ways to define become protected, which means it can only inherit observable class, otherwise you will not be able to call these two methods, it can not achieve observer mode. As a result, it is impossible to Observable class to other classes combined to violation of the "multi-purpose combination, less inheritance" design principles.

protected synchronized void setChanged() {
        changed = true;
}
protected synchronized void clearChanged() {
    changed = false;
}
Published 13 original articles · won praise 0 · Views 72

Guess you like

Origin blog.csdn.net/aaacccadobe/article/details/104017432