定义:
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新。该设计模式最重要的作用就是 解耦!将观察者与被观察者解耦,使得他们之间的依赖性更小。
结构:
下图的结构是一个为上位机接收下位机状态的设计的一个类图。
ObserverRole是观察者抽象类。
AlarmLight和DetectIsStop是具体的观察者(订阅者)。
FaultStatusManager是一个具体的被观察者(发布者)。
当被观察者执行addNewStatusChange(msg)之后,被观察者将会调用notifyRoles(),通知所有List当中的对象的时候(通过执行对象中的update方法)。
package javatest.pattern;
import java.util.ArrayList;
import java.util.List;
/**
* @description: 本类对观察者设计模式进行实现和测试
* @modifyContent:
* @author: Maple Chan
* @date: 2020-07-28 22:08:06
* @version: 0.0.1
*/
public class ObservationPattern {
public static void main(String[] args) {
FaultStatusPublisher faultStatusPublisher = new FaultStatusPublisher();
System.out.println("Role1 subscribe an publisher!");
BaseObserverRole role1 = new AlarmLightRole();
role1.subscribe(faultStatusPublisher);
System.out.println("Role2 subscribe an publisher!");
BaseObserverRole role2 = new DetectIsStopRole();
role2.subscribe(faultStatusPublisher);
System.out.println("\n\n\n");
System.out.println("faultStatusPublisher notify a massage!");
faultStatusPublisher.addNewStatus("alarm: new Message of :" + AlarmLightRole.class);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\n\n\n");
System.out.println("faultStatusPublisher notify another massage!");
faultStatusPublisher.addNewStatus("detect: new Message of :" + DetectIsStopRole.class);
}
}
/*
发布者、被观察者基类
*/
abstract class BasePublisher {
protected List<BaseObserverRole> observerRoles = new ArrayList<>();
/**
* 注册观察者
* @param role
*/
abstract public void attach(BaseObserverRole role);
/**
* 调用BaseObserverRoles的update,通知消息。可以考虑从队列中获取消息,实现消息同步接收发送
* @param msg
*/
abstract protected void notifyRoles(String msg);
/**
* 添加消息,调用notifyRoles方法。可以考虑队列的方式,完成消息的同步
* @param msg
*/
abstract public void addNewStatus(String msg);
}
/*
具体的发布者、被观察者
*/
class FaultStatusPublisher extends BasePublisher {
public void attach(BaseObserverRole role) {
observerRoles.add(role);
}
@Override
protected void notifyRoles(String msg) {
observerRoles.forEach((it) -> {
it.update(msg);
});
}
@Override
public void addNewStatus(String msg) {
// TODO Auto-generated method stub
notifyRoles(msg);
}
}
/*
观察者基类
*/
abstract class BaseObserverRole {
protected BasePublisher statusPublisher;
/**
* 观察者数据处理方法。
*
* @description 观察者抽象类的必要方法,通过该方法对属于自己的数据进行处理
* @author Maple Chan
* @date: 2020-07-28 22:25:46
* @params
* @return
* @param msg
*/
abstract void update(String msg);
/**
* 订阅发布者方法。
*
* @description 观察者抽象类的必要方法,通过该方法进行订阅数据
* @author Maple Chan
* @date: 2020-07-28 22:22:53
* @params statusPublisher
* @return
* @param statusPublisher
*/
abstract void subscribe(BasePublisher statusPublisher);
}
/**
* @description: 一个观察者的实现类
* @modifyContent:
* @author: Maple Chan
* @date: 2020-07-28 22:32:05
* @version: 0.0.1
*/
class AlarmLightRole extends BaseObserverRole {
private final String tag = "alarm";
@Override
public void update(String msg) {
if (msg.contains(tag)) {
System.out.println("This is AlarmLightRole message, tag is " + tag);
System.out.println("AlarmLightRole dealing message: " + msg);
}
}
@Override
void subscribe(BasePublisher faultStatusPublisher) {
this.statusPublisher = faultStatusPublisher;
faultStatusPublisher.attach(this);
}
}
/**
* @description: 一个观察者的实现类
* @modifyContent:
* @author: Maple Chan
* @date: 2020-07-28 22:32:05
* @version: 0.0.1
*/
class DetectIsStopRole extends BaseObserverRole {
private final String tag = "detect";
@Override
public void update(String msg) {
if (msg.contains(tag)) {
System.out.println("This is DetectIsStopRole message, tag is " + tag);
System.out.println("DetectIsStopRole dealing message: " + msg);
}
}
@Override
void subscribe(BasePublisher faultStatusPublisher) {
this.statusPublisher = faultStatusPublisher;
faultStatusPublisher.attach(this);
}
}
// 输出:
/*
Role1 subscribe an publisher!
Role2 subscribe an publisher!
faultStatusPublisher notify a massage!
This is AlarmLightRole message, tag is alarm
AlarmLightRole dealing message: alarm: new Message of :class javatest.pattern.AlarmLightRole
faultStatusPublisher notify another massage!
This is DetectIsStopRole message, tag is detect
DetectIsStopRole dealing message: detect: new Message of :class javatest.pattern.DetectIsStopRole
*/
通过上述代码,完成了一个由一个发布者发布不同消息,不同的订阅者通过判断传入的消息进行响应的处理。该设计模式充分利用了多态的特性。BaseObserverRole引用不同的实例,在发布者调用notify的时候,将调用BaseObserverRole的update方法,该方法根据不同具体的实例,执行对应的方法。