• 【设计一个缓存--针对各种类型的缓存】


    1. 设计顶层接口

    // 定义为一个泛型接口,提供给抽象类使用
    public interface CacheManager<T> {
    	// 获取所有的缓存item
        List<T> getAll();
    	// 根据条件获取某些缓存item
        List<T> get(Predicate<T> predicate);
    	// 设置缓存
        boolean set(T t);
    	// 设置缓存list
        boolean set(List<T> tList);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    有接口必定有实现类或者抽象类,实现接口。
    那为了更好地控制子类的行为,可以做一个抽象类,控制子类行为。

    • 分析:
      • 抽象类作为缓存管理的话,那么就需要提供安全访问数据
      • 需要考虑线程安全问题。
      • 花絮: 不仅要满足上述需求,而且让代码尽量简洁。

    2. 设计抽象类 – AbstractCacheManager

    • 属性设计:
      • 需要一个缓存
      • 需要一个线程安全机制方案
    • 行为设计:
      • 自己的行为:
        • 利用线程安全机制控制缓存的读写。
        • 权限:仅自己可访问
      • 后代的行为:
        • 访问一些简单api方法即可实现安全访问缓存
        • 权限:公共访问
    • 设计模式:
      • 包裹思想,将后代行为方法中,包裹一层安全访问的行为。

    Java Code:

     // properties design:
    protected ConcurrentMap<String, T> cache;
    
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    
    // subclass to implements these abstract methods.
    
    protected abstract List<T> getAllByCache();
    
    protected abstract void setByCache(T t);
    
    protected abstract void setByCache(List<T> tList);
    
    protected abstract List<T> getByCache(Predicate<T> predicate);
    
    // next content needs to consider safety of multithreads. following methods do implements.
    // entry to use
    @Override
    public final List<T> getAll() {
       return this.readLockThenGet(() -> this.getAllByCache());
    }
    
    @Override
    public final List<T> get(Predicate<T> predicate) {
       return this.readLockThenGet(pre -> getByCache(pre), predicate);
    }
    
    @Override
    public final boolean set(T t) {
       return this.writeLockThenSet((Consumer<T>) obj -> set(obj), t);
    }
    
    @Override
    public final boolean set(List<T> tList) {
       return this.writeLockThenSet((Consumer<List<T>>) list -> set(list), tList);
    }
    
    // current abstract class access cache object.
    private boolean writeLockThenSet(Consumer consumer, Object object){
        boolean wLock = false;
        try {
            if (!(wLock = lock.writeLock().tryLock(100, TimeUnit.MICROSECONDS))) {
                return false;
            }
            consumer.accept(object);
            return true;
        } catch (Exception e) {
            return false;
        } finally {
            if(wLock) {
                lock.writeLock().unlock();
            }
        }
    }
    
    private List<T> readLockThenGet(Supplier<List<T>> supplier){
        boolean rLock = false;
        try{
            if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){
                return null;
            }
            return supplier.get();
        }catch (Exception e){
            return null;
        }finally {
            if(rLock) {
                lock.readLock().unlock();
            }
        }
    }
    
    private List<T> readLockThenGet(Function<Predicate<T>, List<T>> function, Predicate<T> predicate){
        boolean rLock = false;
        try{
            if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){
                return null;
            }
            return function.apply(predicate);
        }catch (Exception e){
            return null;
        }finally {
            if(rLock) {
                lock.readLock().unlock();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    3. 具体子类

    3.1 – AlertRuleItemExpCacheManager

    @Component("alertRuleItemExpCacheManager")
    public class AlertRuleItemExpCacheManager<T extends AlertRuleItemExpCache> extends AbstractCacheManager<AlertRuleItemExpCache> {
       @Resource
       private AlertRuleItemExpDao alertRuleItemExpDao;
    
       @Override
       protected List<AlertRuleItemExpCache> getAllByCache() {
           if (null == cache) {
               List<AlertRuleItemExp> alertRuleItemSrcList =
                       alertRuleItemExpDao.selectList(Wrappers.<AlertRuleItemExp>lambdaQuery().eq(AlertRuleItemExp::getDeleted, 0));
               cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache())
                       .collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));
           }
           return cache.values().stream()
                   .sorted(Comparator.comparing(AlertRuleItemExpCache::getId))
                   .collect(Collectors.toList());
       }
    
       @Override
       protected void setByCache(AlertRuleItemExpCache alertRuleItemExpCache) {
           cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache);
       }
    
       @Override
       protected void setByCache(List<AlertRuleItemExpCache> alertRuleItemExpCacheList) {
           alertRuleItemExpCacheList.parallelStream().forEach(alertRuleItemExpCache ->
                   cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache));
       }
    
       @Override
       protected List<AlertRuleItemExpCache> getByCache(Predicate<AlertRuleItemExpCache> predicate) {
           return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3.2 – AlertRuleItemSrcCacheManager

    @Component("alertRuleItemSrcCacheManager")
    public class AlertRuleItemSrcCacheManager<T extends AlertRuleItemSrcCache> extends AbstractCacheManager<AlertRuleItemSrcCache> {
       @Resource
       private AlertRuleItemSrcDao alertRuleItemSrcDao;
    
       @Override
       protected List<AlertRuleItemSrcCache> getAllByCache() {
           if (null == cache) {
               List<AlertRuleItemSrc> alertRuleItemSrcList =
                       alertRuleItemSrcDao.selectList(Wrappers.<AlertRuleItemSrc>lambdaQuery().eq(AlertRuleItemSrc::getDeleted, 0));
               cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache())
                       .collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));
           }
           return cache.values().stream()
                   .sorted(Comparator.comparing(AlertRuleItemSrcCache::getId))
                   .collect(Collectors.toList());
       }
    
       @Override
       protected void setByCache(AlertRuleItemSrcCache alertRuleItemSrcCache) {
           cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache);
       }
    
       @Override
       protected void setByCache(List<AlertRuleItemSrcCache> alertRuleItemSrcCacheList) {
           alertRuleItemSrcCacheList.parallelStream().forEach(alertRuleItemSrcCache ->
                   cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache));
       }
    
       @Override
       protected List<AlertRuleItemSrcCache> getByCache(Predicate<AlertRuleItemSrcCache> predicate) {
           return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    4. 类图关系

    在这里插入图片描述

  • 相关阅读:
    如何用明细数据批量制作卡片
    Design Compiler工具学习笔记(2)
    嵌入式经典面试题
    迅为龙芯开发板固态硬盘启动(烧写系统到固态)-分区
    [附源码]SSM计算机毕业设计基于健身房管理系统JAVA
    Windows 安装 nvm 提示 ‘“node“‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    SSM+中小型企业绩效管理系统毕业设计-附源码081536
    数据分析图片绘制咨询
    dubbo通信原理
    计算机组成原理学习笔记:BCD码
  • 原文地址:https://blog.csdn.net/qq_39118371/article/details/134433789