观察者模式
定义
观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
定义很明确,如果学过Android的童鞋肯定对Android中的广播不陌生,广播就是观察者模式的一种实现。
实现
下面举个例子来说明观察者模式,某个明星在微博发布了一个动态,说他会唱跳rap篮球,然后所有关注他的粉丝都第一时间就收到了他的动态。这就是一个典型的观察者模式,粉丝作为观察者观察明星,明星一旦有状态改变就通知所有粉丝。
首先画出UML类图:
- Observer接口:在此接口中,只声明了一个update()方法,用来更新每个观察者的状态。
- Ikun观察者类:此类实现了Observer接口,是一个实际的观察者,在我们例子中,一个Ikun对象就是Kunkun的粉丝之一。
- Subject接口:在此接口中,声明了添加、删除以及通知观察者的方法。
- Kunkun被观察者类:此类实现了Subject接口,是一个实际的被观察者,用一个ArrayList变量储存Observer,这样addObserver方法就是向ArrayList中add新元素,即为Kunkun添加一个新ikun;removeObserver就是remove某个元素,即为Kunkun踢出一个ikun;notify方法就是遍历所有的Observer,执行update方法,通知所有的ikun。
下面给出Java代码:
Subject.java
package top.liuergo.observer.simple;
/**
* @author liuergo
* @description 被观察者
* @date 2019-11-21 09:59
*/
public interface Subject {
/**
* 为该Subject添加观察者
* @param o 一个观察者对象
*/
public void addObserver(Observer o);
/**
* 删除某个观察者
* @param o 一个观察者对象
*/
public void removeObserver(Observer o);
/**
* 通知所有观察者
*/
public void notifyAllObservers();
}
Observer.java
package top.liuergo.observer.simple;
/**
* @author liuergo
* @description 观察者
* @date 2019-11-21 09:58
*/
public interface Observer {
/**
* 更新观察者的状态
* @param message 状态
*/
public void update(String message);
}
Kunkun.java
package top.liuergo.observer.pratical;
import top.liuergo.observer.simple.Observer;
import top.liuergo.observer.simple.Subject;
import java.util.ArrayList;
import java.util.List;
/**
* @author liuergo
* @description 明星Kunkun
* @date 2019-11-21 10:31
*/
public class Kunkun implements Subject {
private List<Observer> ikuns;
private String message;
public Kunkun() {
ikuns = new ArrayList<>();
}
@Override
public void addObserver(Observer o) {
//为Kunkun增加一个ikun
ikuns.add(o);
}
@Override
public void removeObserver(Observer o) {
//将一个ikun踢出粉丝群
ikuns.remove(o);
}
@Override
public void notifyAllObservers() {
for (Observer ikun : ikuns) {
ikun.update(this.message);
}
}
public void sendMessage(String message) {
this.message = message;
notifyAllObservers();
}
}
Ikun.java
package top.liuergo.observer.pratical;
import top.liuergo.observer.simple.Observer;
/**
* @author liuergo
* @description Kunkun粉丝
* @date 2019-11-21 10:35
*/
public class Ikun implements Observer {
private String name;
public Ikun(String name) {
this.name = name;
}
@Override
public void update(String message) {
//ikun更新自己的状态
System.out.println(name + "收到了消息:" + message);
}
}
Tester.java
package top.liuergo.observer.pratical;
/**
* @author liuergo
* @description 测试类
* @date 2019-11-21 10:46
*/
public class Tester {
public static void main(String[] args) {
Ikun ikunA = new Ikun("张三");
Ikun ikunB = new Ikun("李四");
Kunkun kunkun = new Kunkun();
kunkun.addObserver(ikunA);
kunkun.addObserver(ikunB);
kunkun.sendMessage("我是练习时常两年半的偶像练习生,喜欢唱、跳、rap、篮球~");
}
}
运行结果:
这样Kukun的两个ikun都收到了Kunkun发布的消息。
完整代码地址: https://github.com/liuzhongyue/DesignPatterns