观察者模式和责任链模式

2,295 阅读4分钟

前言

这两天复习OKHttp源码时,看到了一些设计模式,平时写业务逻辑或多或少会使用的,简单记录一下^^--^^

观察者模式和责任链模式都属于行为类设计模式,它们两看似没什么区别,但是触发机制优点类似,都有一个触发链,观察者模式中通知观察者时的调用和责任链模式中调用下一级处理者处理方式。

目录

一、观察者模式

1、观察者模式

韩非子,法家代表人物,主张建立法制社会,实施重罚制度,李斯和韩非子都是荀子的学生,李斯是秦国的上尉,韩非子是韩国的重量级人物,李斯致力于全国统一,于是安排了间谍到韩非子身边,韩非子做的事,李斯都了如指掌。韩非子作为被监控、被观察的对象,韩非子身边的卧底观察一举一动,汇报给李斯。这在设计模式中叫观察者模式。

韩非子作为被观察者,通过卧底持续观察

//被观察者接口
public interface Observable{
    //增加观察者
    public void addObserver(Observer observer);
    //删除观察者
    public void deleteObserver(Observer observer);
    //通知观察者
    public void notifyObservers(String content);
}

接下来看看韩非子是如何实现的

pubilc interface IHanFeiZi{
    public void eat();//吃
    public void haveFun();//玩
}
//韩非子
puiblic class HanFeiZi implements IHanFeiZi,Observable{
    private ArrayList<Observer> observerList = new ArrayList<>();

    public void addObserver(Observer observer){
        observerList.add(observer);
     }
     public void deleteObserver(Observer observer){
         this.observerList.remove(observer);
     }
     public void notifyObservers(String content){
         for(Observer observer:observerList){
             observer.update(content);
         }
     }

    //韩非子开吃了
    public void eat(){
       this.notifyObservers("韩非子开始吃了");
    }
    //韩非子要开始玩了、
    public void haveFun(){
       this.notifyObservers("韩非子开始玩了");
    }

}

观察者李斯

public interface Observer{
    public void update(String content);//别人有动静,通知我后采取措施
}
​
//李斯
public class LiSi implements Observer{
    public void update(String content){
        this.reportToQinShiHuang(content);
    }
    private void reportToQinShiHuang(String content){
        //报告,老板 韩非子有活动了......
    }
}

可能在李斯派卧底到韩非子身边的时候,其他人可能也安插了卧底,

调用方法,场景如下

Observer liSi = new LiSi();
Observer wangSi = new WangSi();
HanFeiZi hanFeiZi = new HanFeiZi();
hanFeiZi.addObserver(liSi);
hanFeiZi.addObserver(wangSi);
hanFeiZi.eat();//一开始吃,大家就都知道了

2、观察者模式优缺点以及应用场景

观察者模式也可以叫发布订阅模式,每当被观察者对象改变状态,所有依赖于它的对象都会通知并更新。

它的优点就是观察者和被观察者之间是抽象耦合的,你可以看一下上述的LiSi和HanFeiZi类,而且也符合单一职责原则,每个类的职责都单一,通过Observer和Observable将单一职责的类串联起来,形成完美的触发机制。

当然,它也有缺点,可以看到上述的notifyObservers(),需要通知每一个观察者,那如果有一个观察者卡壳了,剩下的怎么办,运行不下去了,从而影响整体业务逻辑。解决方法是采用异步的方式,异步的话就需要考虑其他因素了。

使用到观察者模式的常见的技术有RxJava 、 LifeCycler、EventBus等,现实场景有文件系统、ATM取钱、广播收音机等等。

二、责任链模式

多个对象都有机会处理请求

public abstract class Handler{
    private Handler nextHandler;
    //每个处理者对请求做出处理
    public final Response handleMessage(Request request){
        Response response = null;
        if(this.getHandlerLevel().equals(request.getRequestLevel())){
            response = this.echo(request);
        }else{
            //不归自己处理,交给下一级处理
            if(this.nextHandler != null){
                response = this.nextHandler.handleMessage(request);
            }
        }
        return response;
    }
    public void setNext(Handler handler){
        this.nextHandler = handler;
    }
    protected abstract Level getHandlerLevel();
    protected abstract Response echo(Request request);
}

这个类主要是用来定义设置下一个处理者,定义对外开放的handleMessage方法。具体处理者如下

public class ConcreteHandler1 extends Handler{
    protected Response echo(Request request){
        //处理逻辑
        return null;
    }
    protected Level getHandlerLevel(){
        //处理级别
        reutrn null;
    }
}
ConcreteHandler2 类似

调用

Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
handler1.setNext(handler2);
Response response = handler1.handleMessage(new Request());

责任链模式的优点就是将请求和处理分开,请求者不知道这个Request到底是谁处理的,处理的人也不需要知道是谁调用的,缺点就是,如果责任人太多了,链式调用,类似递归,逻辑会比较复杂,加上可能对Request的处理需要遍历所有的处理者,对性能也不友好。建议在具有少数处理者的情况下使用责任链模式,或者对 setNext 设置一个阈值。