参考程杰《大话设计模式》
观察者模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
在一个对象改变需要同时通知其他对象,并且不知道具体有多少对象需要改变时,适合使用观察者模式。
实例
状态枚举
public enum StateTypeEnum {
OFFLINE(0),
ONLINE(1)
;
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
StateTypeEnum(Integer code) {
this.code = code;
}
}
Subject基类,即要通知别人的人
public abstract class Subject {
List<Observer> lists = new ArrayList<>();
public void attach(Observer observer){
lists.add(observer);
}
public void detach(Observer observer){
lists.remove(observer);
}
public void notifyObserver(){
if(CollectionUtils.isNotEmpty(lists)){
lists.forEach(o -> o.update());
}
}
}
Subject的子类,实现类
public class ConcreteSubject extends Subject {
private StateTypeEnum stateTypeEnum;
public StateTypeEnum getSubjectState() {
return stateTypeEnum;
}
public void setSubjectState(StateTypeEnum subjectState) {
this.stateTypeEnum = subjectState;
}
}
Observer基类,即收到通知更新自己的一些状态的人
public abstract class Observer {
abstract void update();
}
Observer的子类,实现类
public class ConcreteObserver extends Observer {
private String name;
private StateTypeEnum typeEnum;
private ConcreteSubject subject;
public ConcreteObserver(Subject subject) {
this.subject = (ConcreteSubject) subject;
}
@Override
public void update() {
System.out.println("更新!");
this.subject.setSubjectState(typeEnum);
System.out.println(this.subject.getSubjectState());
System.out.println("观察者名称" + this.name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public StateTypeEnum getTypeEnum() {
return typeEnum;
}
public void setTypeEnum(StateTypeEnum typeEnum) {
this.typeEnum = typeEnum;
}
}
使用
public class TestdemoApplication {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
ConcreteObserver observerA = new ConcreteObserver(subject);
observerA.setName("AAA");
observerA.setTypeEnum(StateTypeEnum.ONLINE);
subject.attach(observerA);
subject.notifyObserver();
observerA.setTypeEnum(StateTypeEnum.OFFLINE);
subject.notifyObserver();
}
}
输出结果
Java中自带的观察者模式
Java的util包中实现了观察者模式,subject类继承Observable抽象类,Observer实现接口Observer即可。其余attach,detach,notify的方法已经被封装,直接调用即可。
public class SelfSubject extends Observable {
public void update(){
System.out.println("通知更新!");
setChanged();
notifyObservers();
}
}
public class SelfObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("更新!");
}
}
public class TestdemoApplication {
public static void main(String[] args) {
SelfSubject selfSubject = new SelfSubject();
SelfObserver selfObserver = new SelfObserver();
selfSubject.addObserver(selfObserver);
selfSubject.update();
}
}
职责链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
当客户提交一个请求时,请求沿着链传递,知道有一个ConcreteHandler对象处理了请求。链中对象自己不清楚链结构,他们仅需保持一个后继的引用。
实例
职责链基类,保持一个后继者的引用,处理请求方法是抽象的,子类自己实现各自请求逻辑
public abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(int request);
}
子类,实现Handler类,重写请求方法,如果不处理请求,那么传给下一个人处理
public class ConcreteHandlerA extends Handler{
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 20){
System.out.println("ConcreteHandlerA处理请求:" + request);
}else{
if (!Objects.isNull(this.nextHandler)){
this.nextHandler.handleRequest(request);
}
}
}
}
public class ConcreteHandlerB extends Handler{
@Override
public void handleRequest(int request) {
if (request >= 20 && request < 80){
System.out.println("ConcreteHandlerB处理请求:" + request);
}else{
if (!Objects.isNull(this.nextHandler)){
this.nextHandler.handleRequest(request);
}
}
}
}
public class ConcreteHandlerC extends Handler{
@Override
public void handleRequest(int request) {
if (request >= 80 && request < 100){
System.out.println("ConcreteHandlerC处理请求:" + request);
}else{
if (!Objects.isNull(this.nextHandler)){
this.nextHandler.handleRequest(request);
}
}
}
}
使用
public class TestdemoApplication {
public static void main(String[] args) {
int[] requests = {5,70,99};
Handler handler1 = new ConcreteHandlerA();
Handler handler2 = new ConcreteHandlerB();
Handler handler3 = new ConcreteHandlerC();
handler1.setNextHandler(handler2);
handler2.setNextHandler(handler3);
for (int request : requests) {
handler1.handleRequest(request);
}
}
}
输出结果