设计模式-观察者模式

观察者模式

饿了要吃饭,累了要休息

策略模式中,我们根据一个条件来判定状态,然后选择具体的处理策略。

这是官方的,必要的,明确规定的流程,更是业务的明确需求。

同时,还有模板方法让我让我们进行流程填充。

更多的不必赘述,纵观之前的模式,都是选择,但是有时候,我们更需要触发


正如开篇,饿了要吃,累了要睡,我们知道如何去吃、如何去睡,但是,我们的状态怎么知道呢。

或者可以使用策略模式来无限监听

Created with Raphaël 2.2.0 start process error? end trigger status? trigger strategy yes no yes no
while True:
  status = task.getStatus()
  statusHandler = statusHandlerStragy.searchHandler(status)
  if not status:
    continue
 	statusHandler.handle(task)

纠正错误

不得不说,上面的方式有点蠢,因为状态的变化只有对象本身最清楚,一直监听实在浪费。

这种周期监听的极大消耗在于稳定状态时候的纯监听开销。

正如数据库和缓存的同步问题,如果以周期的去同步数据库,如果两亿年不更新底裤。

那么这两亿年有多少消耗,全是无用功,尤其为了业务的精准,同步周期都是在秒级。

这就是所谓观察者模式让人诟病的点,因为观察真的没啥好处,更多的其实是通知。

还不如说是状态报备模式。

不过也能够换另一种方式去观察一下。

def kernel():
  print("kernel")
  
def kernelWrapper()
	beforeListen()
  kernel()
  afterListen()

让它调用的时候,一定过我的封装,这好像也行。

不过,这个东西好像串门了,装饰器模式或者代理模式,aop也可以,暂时就不说这个。

而且这个有坑,如果我调用了原始的方法,这就完全没什么用了。

通知方式

interface

public interface IHandler {
    void handle();
}

context

public class Context {

    IHandler prepareHandler;
    IHandler closeHandler;
    IHandler processHandler;

    public void registerPrepareHandler(IHandler handler){
        this.prepareHandler = handler;
    }
    public void registerCloseHandler(IHandler handler){
        this.closeHandler = handler;
    }
    public void registerProcessHandler(IHandler handler){
        this.processHandler = handler;
    }
    public void prepare(){
        this.prepareHandler.handle();
    }
    public void close(){
        this.closeHandler.handle();
    }
    public void process(){
        this.processHandler.handle();
    }
}

不过,一般规范的处理,才不是这样直接触发,缺乏管理。

process listener handler 发出事件 匹配处理 process listener handler

也就是说,以event来进行管理,来关联,这样就避免了枚举的尴尬。

public abstract class EventManager implements IHandler{
    static ConcurrentHashMap<String, IHandler> eventCollection = new ConcurrentHashMap<>();

    @PostConstruct
    public void register(){
        eventCollection.put(getClass().getSimpleName(), this);
    }

    public static void handleEvent(String event){
        if(!eventCollection.containsKey(event)){
            return;
        }
        eventCollection.get(event).handle();
    }
}

如果为了触发方便,可以单独出一个文件,作为事件列表,方便注册和调用两方面对接。

public interface EventConstant {
    String PREPARE_EVENT = "prepare";
    String PROCESS_EVENT = "process";
}
public abstract class EventManager implements IHandler{
    static ConcurrentHashMap<String, IHandler> eventCollection = new ConcurrentHashMap<>();

    @PostConstruct
    public void register(){
        eventCollection.put(getName(), this);
    }

    public static void handleEvent(String event){
        if(!eventCollection.containsKey(event)){
            return;
        }
        eventCollection.get(event).handle();
    }

    public abstract String getName();
}

实例注册如下

public class PrepareEventHandler extends EventManager {
    @Override
    public String getName() {
        return EventConstant.PREPARE_EVENT;
    }

    @Override
    public void handle() {
        System.out.println("prepare");
    }
}

小结

观察?不存在的,观察是不可能观察的,这辈子都是不可能观察的。

只能偶尔通知一下,才能勉强的把日子过下去。

现在的listener,都是骗人的,他们从来不是去监听什么然后主动调用,都是被调用的。

很少出现你通知,我办事那种情况,更多时候都是,听我号令,开干

不过,纯正的观察者模式使用能力不强,只有在强大的的管理下才能迸发活力。

比如各大框架的繁复的生命周期,以及各种订阅,更关注流程和处理。

所以,现在的开发,更多是去注册处理方法,从头的埋点,怕是机会不多。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值