观察者模式实现
1. 观察者模式Overview
- 定义了一种一对多的交互方式,可以被观察的对象可以通知所有观察者他们期待的对象的变化,Pull vs Push.
- 当一个对象改变状态的时候,它的所有依赖者都会收到通知并且会自动更新
- Subject/ Observable
- 管理某些数据
- 当数据改变的时候,通知订阅者
- Observer
- 在订阅的数据发生改变了以后,得到通知
2. 使用场景
- 出版者 + 订阅者
- Check Java Observable, though deprecated
3. 使用目的
- 责任的分开,只有一份数据,由Observable来进行管理,
- Observer只是拿到了数据的更新,然后做自己特定的事情,observable完全不需要知道这里的细节。用这种方式实现了交互对象之间的松耦合
4. 具体实现
4.1 接口和数据对象定义
/**
* Observer other abilities
*/
public interface IDisplay {
void display();
}
/**
* Observable interface, used to register/remove/notify observers
*/
public interface IObservable {
ActionResult registerObserver(IObserver observer);
ActionResult removeObserver(IObserver observer);
void notifyObservers();
}
/**
* Observable will call update method for regiestered observer to update the status in observer side
*/
public interface IObserver {
void update(SharebleData data);
@Data
@RequiredArgsConstructor
@AllArgsConstructor
public class SharebleData {
Double temperature;
Double humidity;
Double pressure;
}
public enum Status {
SUCCESS,
FAILURE
}
@Data
@AllArgsConstructor
public class ActionResult {
@NonNull
Status status;
@Nullable
List<String> errorReason;
}
4.2 具体实现类的定义
public class ObservableImpl implements IObservable{
private static List<IObserver> observerList;
private SharebleData data;
public ObservableImpl() {
observerList = new ArrayList<>();
data = new SharebleData();
}
public void setSharebleData(double tem, double humidity, double pressure) {
data.setHumidity(humidity);
data.setTemperature(tem);
data.setPressure(pressure);
notifyObservers();
}
@Override
public ActionResult registerObserver(IObserver observer) {
observerList.add(observer);
return new ActionResult(Status.SUCCESS, null);
}
@Override
public ActionResult removeObserver(IObserver observer) {
observerList.remove(observer);
return new ActionResult(Status.SUCCESS, null);
}
@Override
public void notifyObservers() {
observerList.forEach(observer -> {observer.update(data);});
}
}
public class CurrentConditionDisplay implements IObserver, IDisplay{
private double temp;
private double pressure;
private IObservable observable;
public CurrentConditionDisplay(IObservable subject) {
this.observable = subject;
observable.registerObserver(this);
}
@Override
public void display() {
System.out.println(String.format("======= print out current tem and pressure! temp: %f, pressure: %f ", temp, pressure));
}
@Override
public void update(SharebleData data) {
temp = data.getTemperature();
pressure = data.getPressure();
display();
}
}
4.3 测试
@RestController
public class TestController {
@GetMapping("/observer")
public String observer() {
StringBuilder sb = new StringBuilder();
ObservableImpl observable = new ObservableImpl();
observable.setSharebleData(30, 0.7, 80);
CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(observable);
observable.setSharebleData(31, 0.7, 80);
observable.setSharebleData(32, 0.7, 80);
observable.setSharebleData(33, 0.7, 80);
return "Please check log";
}
}
// Output from console
======= print out current tem and pressure! temp: 31.000000, pressure: 80.000000
======= print out current tem and pressure! temp: 32.000000, pressure: 80.000000
======= print out current tem and pressure! temp: 33.000000, pressure: 80.000000
Reference
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com
文章标题:观察者模式实现
文章字数:613
本文作者:Leilei Chen
发布时间:2022-09-17, 11:49:49
最后更新:2022-09-17, 11:53:15
原始链接:https://www.llchen60.com/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F-1/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。