DesignPattern - 观察者模式【行为型】

547 阅读2分钟

欢迎关注微信公众号:FSA全栈行动 👋

一、观察者模式介绍

观察者模式(Observer)定义了对象间一种一对多的依赖关系,使得每当一个对象改变状态时,所以依赖于它的对象都会得到通知并自动更新,也叫做发布订阅模式 Publish/Subscribe,属于行为型模式

  • 核心组成

    • Subject 主题:持有多个观察者对象的引用,抽象主题提供了一个接口可以增加和删除观察者对象;有一个观察者数组,并实现增、删及通知操作
    • Observer 抽象观察者:为具体观察者定义一个接口,在得到主题的通知时更新自己
    • ConcreteSubject 具体主题:将有关状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知
    • ConcreteObserver 具体观察者:实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态保持一致
  • 应用场景

    • 消息通知,比如邮件通知、广播通知、微信朋友圈、微博私信等,都是监听观察事件
    • 当一个对象的改变需要同时改变其它对象,且它不知道具体有多少对象有待改变的时候,考虑使用观察者模式
  • 优点

    • 降低了目标与观察者之间的耦合关系,目标与观察者之间建立了一套触发机制
    • 观察者和被观察者是抽象的
  • 缺点

    • 观察者和观察目标之间有循环依赖的话,会触发它们之间进行循环调用,可能导致系统崩溃
    • 一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间

二、观察者模式代码实现

创建抽象主题类:

/**
 * 抽象主题
 *
 * @author GitLqr
 */
public class Subject {
	private List<Observer> observerList = new ArrayList<>();

	public void add(Observer observer) {
		observerList.add(observer);
	}

	public void remove(Observer observer) {
		observerList.remove(observer);
	}

	public void notifyAllObservers() {
		for (Observer observer : observerList) {
			observer.update();
		}
	}
}

创建抽象观察者类:

/**
 * 观察者
 *
 * @author GitLqr
 */
public abstract class Observer {
	public abstract void update();
}

创建具体主题类:

/**
 * 具体主题:QQ新闻推送
 *
 * @author GitLqr
 */
public class QQNewsSubject extends Subject {

	public void pushNews() {
		notifyAllObservers();
	}
}

创建具体观察者类:

/**
 * 具体观察者:QQ
 *
 * @author GitLqr
 *
 */
public class QQObserver extends Observer {

	@Override
	public void update() {
		System.out.println("QQ 收到了新闻推送");
	}
}

/**
 * 具体观察者:Tim
 *
 * @author GitLqr
 *
 */
public class TimObserver extends Observer {

	@Override
	public void update() {
		System.out.println("Tim 收到了新闻推送");
	}
}

使用:

public static void main(String[] args) {
    // 创建一个主题:QQ新闻
    QQNewsSubject subject = new QQNewsSubject();

    // 创建多个QQ号
    Observer qq1Observer = new QQObserver();
    Observer qq2Observer = new TimObserver();

    // 订阅主题
    subject.add(qq1Observer);
    subject.add(qq2Observer);

    // 推送QQ新闻
    subject.pushNews();
}

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~