设计模式学习笔记--观察者模式(Observer Pattern)

概念

观察者模式定义了对象之间的一对多的依赖关系,当一个对象(被观察者)改变状态时,它的所有依赖者(观察者)都会收到通知并更新

设计原则

为了交互对象之间的松耦合设计而努力

理解

在这个模式中存在两个角色,一个是 “被观察者”,另一个是 “观察者”,他们之间的关系类似现实生活中的“报刊订阅”,其中被观察者是“报社”,观察者是“用户”,用户在报社购买报刊订阅服务后,报社一旦有新报刊发布,就会通知用户,而如果用户取消订阅,以后报社就不会通知该用户。从报社通知用户到用户得到报刊有两种过程,一种是报社将报刊送到用户家里(push),另一种是用户自己到报社取(pull),其中第一种过程是不管用户是否需要这份报刊,报社都会将最新的报刊送到用户家里,而第二种是用户根据自己的需要,到报社取需要的报刊,这是两种过程的区别。

组成

  • 抽象主题(Subject):也就是抽象被观察者接口,提供增加删除和通知观察者的方法
  • 抽象观察者(Observer):观察者接口,提供更新的方法
  • 具体主题(ConcreteSubject):实现抽象主题接口,因此具有增加删除通知观察者的方法,
  • 具体观察者(COncreteObserver):实现抽象观察者接口,注册具体主题后就可以接收到通知更新

下面是观察者模式的类图

设计模式学习笔记--观察者模式(Observer Pattern)_第1张图片

实例

以下代码模拟一个报刊订阅的过程,有一家叫做 DailyNews 的报社,Tom 和 Jerry 都注册了这家报社的最新消息订阅服务,每当有最新消息到来,报社就会通知他们,接着 Tom 取消了这个服务,则报社的最新消息不会通知 Tom 而只通知 Jerry。在这个过程中,DailyNews 报社扮演被观察者角色,Tom 和 Jerry 两个用户扮演观察者角色

定义抽象用户接口类:User

定义了具体用户与具体报社之前的通信接口,通过这个接口,报社可以将通知更新给所有已注册用户

public interface User {

    public void update(String content);
}

定义抽象报社接口类:NewsPaper

具体报社需要具有 注册观察者,删除观察者,通知观察者的功能,因此抽象报社定义了这三个通用的方法

public interface NewsPaper {

    public void registerUser(User u);
    public void removeUser(User u);
    public void notifyNews(String content);
}

定义具体报社类:DailyNews

这是一家叫做 DailyNews 的报社,用户可以在这里注册订阅,也可以取消订阅,报社会将最新消息通知给用户

public class DailyNews implements NewsPaper {

    private List userList;

    public DailyNews() {
        userList = new ArrayList<>();
    }

    @Override
    public void registerUser(User u) {
        userList.add(u);
    }

    @Override
    public void removeUser(User u) {
        userList.remove(u);
    }

    @Override
    public void notifyNews(String content) {
        for (User u:userList){
            u.update(content);
        }
    }
}

定义具体用户类:Tom 和 Jerry

Tom 和 Jerry 是两个用户,他们可以订阅报社的最新消息,一旦报社有最新消息,就会通过 update() 方法通知给他们

public class TomUser implements User{
    @Override
    public void update(String content) {
        System.out.println("Tom 收到最新消息: "+content);
    }
}
public class JerryUser implements User {
    @Override
    public void update(String content) {
        System.out.println("Jerry 收到最新消息: "+content);
    }
}

测试

测试类中模拟上面描述的实例需求

public class MainTest {
    public static void main(String[] args) {
        DailyNews daily = new DailyNews();

        User tom = new TomUser();
        User jerry = new JerryUser();

        //向报社注册用户
        daily.registerUser(tom);
        daily.registerUser(jerry);

        daily.notifyNews("DailyNews报社今日最新消息");

        System.out.println("用户 tom 退订了");
        daily.removeUser(tom);
        daily.notifyNews("DailyNews报社明日消息");
    }
}

运行效果

设计模式学习笔记--观察者模式(Observer Pattern)_第2张图片

以上,一个简单的观察者模式的实例就实现了,目前对这个模式的理解还比较粗浅,希望在以后的学习中能够深入理解这种模式

//胡思乱想:观察者模式和回调。。。有点混乱,那Android中的点击事件举例,其实使用观察者模式也是可以实现的吧,界面是被观察者,系统的触摸事件响应是观察者,当用户点击界面,触发被观察者更新,那么系统就能接收到这个更新,然后继续处理了。而回调呢,界面中把按键事件编写好,系统在接收到用户触摸事件时再去吊用这个事件,这样,额,先这样吧

你可能感兴趣的:(设计模式)