行为型设计模式 — 观察者模式

有高尚思想的人永不会孤独的。 — 西德尼

写在前面

观察者模式的定义:定义对象间一种一对多的依赖关系,每当一个对象改变状态时,则所有依赖它的对象都会得到通知并被自动更新。

观察者模式.jpg

抽象被观察者类(Subject):把所有的观察者对象保存在一个集合里,每个被观察者都可以由任意数量的观察者,抽象主题类提供一个接口,可以增加和删除观察者对象。
具体被观察者类(ConcreteSubject):该角色将有关状态存入具体观察者对象,在具体被观察者内部发生改变时,给所有注册过的观察者发送通知。
抽象观察者类(Observer):是观察者的抽象类,它定义了一个更新接口,使得在得到被观察者更改通知时更新自己。
具体观察者类(ConcreteObserver):实现抽象观察者定义的更新接口,以便在得到被观察者更改通知时更新自身的状态。

如何观察

下面通过一个例子来认识观察者模式:

小明,小红和李雷因为上课捣蛋被老师拉到办公司罚站了,老师不放他们谁也不能走,只能继续罚站,直到老师说“你们可以回去上课了”。

1.抽象观察者类

因为小明,小红和李雷都要等老师说“你们可以回去上课了”这个行为,也就是要等老师的通知,所以三名同学是观察者,观察老师何时放人,就要定义一个等待通知的接口。

/**
 * 抽象观察者类
 */
public interface Observer {
    
    void update();
}
2.具体观察者类

因为小明,小红和李雷都要等老师说“你们可以回去上课了”这个行为,所以要观察老师的行为,每个人都要实现等待通知的接口。

/**
 * 具体观察者类
 */
public class XiaoMingObserver implements Observer {
    @Override
    public void update() {
        Log.d("小明", "小明可以回去继续上课了");
    }
}

/**
 * 具体观察者类
 */
public class XiaoHongObserver implements Observer {
    @Override
    public void update() {
        Log.d("小红", "小红可以回去继续上课了");
    }
}

/**
 * 具体观察者类
 */
public class LiLeiObserver implements Observer {
    @Override
    public void update() {
        Log.d("李雷", "李雷可以回去继续上课了");
    }
}
3.抽象被观察者类

三名同学都要等待老师的通知,所以老师是被观察者。现来定义一个被观察者的接口。

/**
 * 抽象被观察者
 */
public interface Subject {
    
    void attach(Observer observer);
    
    void detach(Observer observer);
    
    void notifyAllObserver();
}
4.具体被观察者类

三名同学都要等待老师的通知,所以老师是被观察者。实现抽象被观察者类,并提供一个集合保存所有的观察者,以便向所有注册的观察者发送通知。

/**
 * 具体被观察者类
 */
public class ConcreteSubject implements Subject {

    private ArrayList<Observer> mObservers;

    public ConcreteSubject() {
        mObservers = new ArrayList<>();
    }

    @Override
    public void attach(Observer observer) {
        mObservers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        mObservers.remove(observer);
    }

    @Override
    public void notifyAllObserver() {
        for (Observer observer : mObservers) {
            observer.update();
        }
    }
}
5.通知

老师心情突然好了,说了句“你们可以回去上课了”,三名同学得到了老师的通知,全部回到教室继续上课。

/**
 * 客户端
 */
public class Client {
    
    public Client() {
        // 创建被观察者,向被观察者注册观察者
        ConcreteSubject subject = new ConcreteSubject();
        subject.attach(new XiaoMingObserver());
        subject.attach(new XiaoHongObserver());
        subject.attach(new LiLeiObserver());
        // 被观察者发送通知
        subject.notifyAllObserver();
    }
}

总结

观察者模式的使用场景:

  • 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。
  • 事件多级触发场景。
  • 跨系统的消息交换场景,如消息队列,事件总线的处理机制。

观察者模式的优点:

  • 观察者和被观察者之间是抽象耦合,容易扩展。
  • 方便建立一套触发机制。

观察者模式的缺点:

  • 在应用观察者模式时需要考虑一下开发效率和运行效率问题。程序中包括一个被观察者,多个观察者,开发,调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行的,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步方式。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容