设计模式总结——观察者模式

212 阅读3分钟

定义

在对象之间定义了一种一对多的依赖关系,当一个对象改变状态的时候,所有依赖它的对象都会收到通知并更新。简单讲就是一种发布订阅模式,发布者发布消息,订阅者接收消息

首先先明白两个单词的意思:Observable(被观察者),Observer(观察者)

开发中如何使用?

1.自己实现观察者模式
2.使用jdk自带的api

自己实现观察者模式

需要的类:

抽象观察者类
抽象被观察者类
具体观察者类
具体被观察者类

步骤:

  • 新建抽象观察者类,通常习惯是暴漏出update()用于子类接受更新
  • 新建抽象被观察者类 在该类中进行观察者的添加删除和通知
  • 新建具体被观察者类,实现抽象被观察者类,然后使用List集合保存持有依赖的观察者
  • 新建具体的观察者,实现抽象观察者接口,在update回调中处理自己的逻辑

具体实现代码:

// 新建抽象观察者类
public interface IUserObserver {
    void update(String message);
}
// 新建抽象被观察者类
public interface IUserObservable {
    void addObserver(IUserObserver observer);
    void removeObserver(IUserObserver observer);
    void notifyObserver();
}

// 新建具体被观察者类
public class UserObservable implements IUserObservable {
    //使用List集合保存持有依赖的观察者
    private List<IUserObserver> observerList;
    private String message;
    public UserObservable() {
        this.observerList = new ArrayList<>();
    }
    @Override
    public void addObserver(IUserObserver observer) {
        observerList.add(observer);
    }
    @Override
    public void removeObserver(IUserObserver observer) {
        if(observerList.contains(observer)){
            observerList.remove(observer);
        }
    }
    public void setMessage(String message) {
        this.message = message;
        notifyObserver();
    }
    @Override
    public void notifyObserver() {
        for (IUserObserver iUserObserver : observerList) {
            iUserObserver.update(this.message);
        }
    }
}

  // 新建具体观察者类,在update中处理自己的逻辑
    public class UserObserver implements IUserObserver {
        @Override
        public void update(String message) {
            System.out.println("观察者收到消息: " + message);
        }
}

// 测试类:
public static void main(String[] args) {
        UserObservable userObservable = new UserObservable();
        UserObserver user1 = new UserObserver();
        userObservable.addObserver(user1);
        userObservable.setMessage("用户1的消息");

    }
    
    结果:
    观察者收到消息: 用户1的消息

使用jdk自带api

//新建被观察者类
public class UserObservable2 extends Observable {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void notifyChanged(){
    //在调用notifyObservers前必须先调用setChanged(),否则观察者收不到通知
        setChanged();
        notifyObservers();
    }
}

// 实现观察者类
public class UserObserver2 implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        if(o instanceof UserObservable2){
            UserObservable2 user = (UserObservable2)o;
            String message = user.getMessage();
            System.out.println("观察者2收到消息:" + message);
        }
    }
}

总结:
使用jdk自带api的化有几点需要注意
* 被观察者类继承Observable,在需要通知观察者的时候需要setChanged(),notifyObservers()同时调用
* 观察者类需要实现Observer接口,实现update方法,在这里需要注意update(Observable o, Object arg)的两个
  形参,一个是Observable,即被观察者,也就是该观察者需要观察的那个被观察者,第二个参数是一个Object类型的
  数据,这个数据跟被观察者更新数据时的参数是保持一致的,也就是notifyObservers(Object arg);
* 所以观察者可以在update方法中通过第一个参数Observable和instanceof来区分是哪个被观察者,通过第二个参数可以拿到被观察者发送过来的数据