zoukankan      html  css  js  c++  java
  • 使用 Laravel 的 监听者模式实现缓存机制的松散耦合

    使用 Laravel 的 监听者模式实现缓存机制的松散耦合

    一、总结

    一句话总结:

    1、既然要实现松散耦合的缓存机制,那就是要做到有没有缓存都没事。有缓存的话就走缓存,然后那边的模块内部实现一个包括过期时间呀啥啥的缓存机制,没有收到缓存模块的响应的时候就继续走原来的应用逻辑,一样可以正常响应。
    2、因为我们是要实现应用逻辑与缓存逻辑的解耦,所以正常应用逻辑内是不能有对那些缓存的依赖的。那么我们要通过什么来和缓存模块通信呢?巧的是,Laravel 正好提供了基于 Event 和 Listener 的观察者模式,我们就可以用这种设计模式来解耦缓存模块。

    二、使用 Laravel 的 监听者模式实现缓存机制的松散耦合

    转自或参考:使用 Laravel 的 监听者模式实现缓存机制的松散耦合 - PRIN 的专栏 - SegmentFault 思否
    https://segmentfault.com/a/1190000006916271

    既然要实现松散耦合的缓存机制,那就是要做到有没有缓存都没事。有缓存的话就走缓存,然后那边的模块内部实现一个包括过期时间呀啥啥的缓存机制,没有收到缓存模块的响应的时候就继续走原来的应用逻辑,一样可以正常响应。

    因为我们是要实现应用逻辑与缓存逻辑的解耦,所以正常应用逻辑内是不能有对那些缓存的依赖的。那么我们要通过什么来和缓存模块通信呢?巧的是,Laravel 正好提供了基于 Event 和 Listener 的观察者模式,我们就可以用这种设计模式来解耦缓存模块。

    首先,我们在即将获取一个可能需要缓存的数据之前,触发一个 GetDataEvent(举个栗子),接下来判断这个 Event 是否返回了响应,如有则使用响应的内容,没有的话就继续正常的应用逻辑来获取数据。

    譬如说,我们需要把皮肤的预览图给缓存下来,而不是每次都去生成:

    <?php
    
    namespace AppEvents;
    
    use AppEventsEvent;
    use AppModelsTexture;
    use IlluminateQueueSerializesModels;
    
    class GetSkinPreview extends Event
    {
        use SerializesModels;
    
        public $texture;
    
        public $size;
    
        /**
         * 这里我们并没有做什么,就是把实例化时传进来的参数保存到对象里去
         *
         * @return void
         */
        public function __construct(Texture $texture, $size)
        {
            $this->texture = $texture;
            $this->size    = $size;
        }
    }
    
    // 控制器中的方法
    public function preview($tid, $size = 250)
    {
        // 触发事件
        $responses = Event::fire(new GetSkinPreview($t, $size));
    
        // 当然,如果你有多个 Listener 的话,在这里你可能需要遍历 Event 所返回的响应
        if (isset($responses[0]) && $responses[0] instanceof SymfonyComponentHttpFoundationResponse) {
            // 这个返回的响应类型是看你自己对 Event 的需求的
            // 比如这里我们需要 Listener 返回一个 Http 响应流
            return $responses[0];
        } else {
            /* 原来业务逻辑中的生成预览 */
    
            return Response::png();
        }
    }

    而这个 GetDataEvent,我们是可以注册 Listener 上去的,具体如何添加 Event 和 Listener 请参考 Laravel 文档。假设我们在这里给这个事件注册了一个 CacheDataListener,那么在 GetDataEvent 这个事件在应用逻辑中被触发的时候,Laravel 的 Event Dispatcher 就会把事件分发到我们刚刚注册的监听器里,我们就可以在监听器的 handle 方法中处理缓存逻辑并返回缓存后的数据了。

    <?php
    
    namespace AppListeners;
    
    use Storage;
    use AppEventsGetSkinPreview;
    
    class CacheSkinPreview
    {
        /**
         * 处理缓存逻辑并返回一个 Http 响应流
         *
         * @param  GetSkinPreview  $event
         * @return void
         */
        public function handle(GetSkinPreview $event)
        {
            $tid = $event->texture->tid;
    
            if (!Storage::disk('cache')->has("preview/$tid")) {
                /* 这里生成预览并保存到缓存文件 */
            }
    
            return Response::png(Storage::disk('cache')->get("preview/$tid"));
        }
    }

    这样下来,我们就可以让应用逻辑和缓存逻辑(差不多)完全分离开来,想要使用其他的缓存驱动,例如 Redis 的话,只要新建一个 Listener 并监听 GetDataEvent 就可以了。你甚至可以把缓存机制放到插件里去,而这也就是我本来的目的(笑)

     
  • 相关阅读:
    spring boot Jar
    通过JS判断设备类型
    JS获取本周、上月、本月、上月的开端日期、停止日期
    移动端长按删除事件
    获取浏览器的User Anent及判断微信浏览器
    jquery.range.js左右滑动选取数值插件,动态改变进度。
    JAVA 基础 /第九课: 变量 / JAVA中 什么是变量
    dva基本用法
    Generator 简介
    使用vuex的流程随笔
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/12624219.html
Copyright © 2011-2022 走看看