Java设计模式之观察者模式

126 阅读2分钟

参考资料

当一个对象改变时,发通知给所有订阅它的对象。

示例代码:

package com.cc.observer;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * 被订阅的对象
 * @author cc
 * @date 21-12-20 23:41
 */
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();
        }
    }
}

创建三个观察者对象:

package com.cc.observer;
​
/**
 * 观察者接口
 * @author cc
 * @date 21-12-20 23:45
 */
public abstract class Observer {
    protected Subject subject;
    public abstract void update();
}
package com.cc.observer;
​
public class BinaryObserver extends Observer{
    public BinaryObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }
​
    @Override
    public void update() {
        System.out.println("Binary String: " + Integer.toBinaryString(subject.getState()));
    }
}
package com.cc.observer;
​
public class HexaObserver extends Observer{
    public HexaObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }
​
    @Override
    public void update() {
        System.out.println("Hex String: " + Integer.toHexString(subject.getState()).toUpperCase());
    }
}
package com.cc.observer;
​
public class OctalObserver extends Observer {
    public OctalObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }
​
    @Override
    public void update() {
        System.out.println("Octal String: " + Integer.toOctalString(subject.getState()));
    }
}

测试一下:

package com.cc.observer;
​
public class Main {
    public static void main(String[] args) {
        Subject subject = new Subject();
​
        new HexaObserver(subject);
        new OctalObserver(subject);
        new BinaryObserver(subject);
​
        System.out.println("First state change: 15");
        subject.setState(15);
        System.out.println("Second state change: 10");
        subject.setState(10);
    }
}

结果:

First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010

从示例代码的测试效果可以看到,在subject对象发生变化并发出通知后,订阅了subject对象的三个观察者都接收到了消息并作出了反应。

观察者模式的优缺点

优点:

  • 降低了目标和观察者之间的耦合性,两者是抽象耦合关系,符合依赖倒置原则。
  • 目标和观察者之间建立了一套触发机制

缺点:

  • 目标和观察者之间的依赖关系没有完全解除,可能出现循环引用
  • 当观察者很多时,发布通知会花费很多时间,影响程序效率