观察者模式

 概述

观察者模式(Observer Pattern)定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己属于行为型模式。观察者模式有时也叫发布-订阅模式。观察者模式主要用于在关联者之间建立一套触发机制的场景。生活中也有类似场景比如微信朋友圈动态通知、邮件通知、广播通知等等。

看下类图

看一下简单的观察者模式实现

抽象主题类

public abstract class Subject {
    private List<Observer> observers = new ArrayList<Observer>();
    
    public void attach(Observer observer)
    {
        observers.add(observer);
    }

    public void detch(Observer observer)
    {
        observers.remove(observer);
    }

    public void notifyObserver()
    {
        for (Observer observer:observers) {
            observer.update();
        }
    }
}

抽象观察者接口

public interface Observer {
    public abstract void update();
}

具体主题类

public class ConcreteSubject extends Subject{
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
    }
}

具体观察者

public class ConcreteObserver implements Observer {
    private String name;
    private ConcreteSubject subject;

    public ConcreteObserver(String name, ConcreteSubject subject) {
        this.name = name;
        this.subject = subject;
    }

    @Override
    public void update() {
        System.out.println("观察者" + name + "通知信息:"+ subject.getSubjectState());
    }
}

测试类

public class Client {
    public static void main(String[] args) {
        ConcreteSubject s = new ConcreteSubject();
        s.attach(new ConcreteObserver("X",s));
        s.attach(new ConcreteObserver("Y",s));
        s.setSubjectState("ABC");
        s.notifyObserver();
    }
}

结果

 其实JDK本身也提供了观察者模式的API,下面利用JDK提供的观察者模式API,编写一个在某平台上提交问题通知老师的例子

某教育平台(被观察者继承Observable

public class EduForum extends Observable {
    private String name = "XX教育论坛";
    private static EduForum eduForum = null;
    private EduForum(){}

    public String getName() {
        return name;
    }

    public static EduForum getInstance()
    {
        if (eduForum == null)
            eduForum = new EduForum();
        return eduForum;
    }
    public void publichQuestion(Question question)
    {
        System.out.println(question.getUsername()+ "在" + this.name + "上提交一个问题");
        setChanged();
        notifyObservers(question);
    }
}

问题类

public class Question {
    private String username;
    private String content;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

老师类(观察者)

public class Teacher implements Observer {
    private String name;

    public Teacher(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        EduForum eduForum = (EduForum) o;
        Question question = (Question) arg;
        System.out.println("===============================");
        System.out.println(this.name + "老师,收到一个来自"
                + eduForum.getName() + "的一个问题,\n内容是:"
                + question.getContent() + "\n提问者是:"
                + question.getUsername());
    }
}

测试类

public class Client {
    public static void main(String[] args) {
        EduForum eduForum = EduForum.getInstance();
        Teacher zhao = new Teacher("张三");
        Teacher li = new Teacher("李四");
        eduForum.addObserver(zhao);
        eduForum.addObserver(li);

        Question question = new Question();
        question.setUsername("小明");
        question.setContent("观察者模式适用哪些场景?");

        eduForum.publichQuestion(question);
    }
}

结果

 

posted @ 2019-04-22 16:06  dum  阅读(361)  评论(0编辑  收藏  举报