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

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

  • [1. 设计顶层接口](#1. 设计顶层接口)
  • [2. 设计抽象类 -- AbstractCacheManager](#2. 设计抽象类 -- AbstractCacheManager)
  • [3. 具体子类](#3. 具体子类)
    • [3.1 -- AlertRuleItemExpCacheManager](#3.1 -- AlertRuleItemExpCacheManager)
    • [3.2 -- AlertRuleItemSrcCacheManager](#3.2 -- AlertRuleItemSrcCacheManager)
  • [4. 类图关系](#4. 类图关系)

1. 设计顶层接口

java 复制代码
// 定义为一个泛型接口,提供给抽象类使用
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);
}

有接口必定有实现类或者抽象类,实现接口。

那为了更好地控制子类的行为,可以做一个抽象类,控制子类行为。

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

2. 设计抽象类 -- AbstractCacheManager

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

Java Code:

java 复制代码
 // 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();
        }
    }
}

3. 具体子类

3.1 -- AlertRuleItemExpCacheManager

java 复制代码
@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());
   }
}

3.2 -- AlertRuleItemSrcCacheManager

java 复制代码
@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());
   }
}

4. 类图关系

相关推荐
界面开发小八哥4 分钟前
「Java EE开发指南」如何使用Visual JSF编辑器设计JSP?(二)
java·ide·java-ee·开发工具·myeclipse
zybishe25 分钟前
计算机毕业设计原创定制(免费送源码)Java+SpringBoot+MySQL SpringBoot物流配送后台系统
java·css·c++·spring boot·spark·django·课程设计
BIM云平台开发27 分钟前
关于return,yield 和 yield return
java·开发语言·数据结构·c#
NiNg_1_23429 分钟前
Redis中的zset底层实现
数据库·redis·缓存
GGBondlctrl35 分钟前
【Spring MVC】关于Spring MVC编程中与http请求的参数传递的详细介绍
java·spring·mvc·postman·请求参数的传递·json的传递
小小unicorn37 分钟前
基于Boost库的搜索引擎
java·搜索引擎·dubbo
m0_7482329237 分钟前
JVM的内存区域划分
java·jvm·算法
遇见你真好。43 分钟前
x-easypdf 初始与简单使用
java·springboot·x-easypdf
菜鸟挣扎史1 小时前
关于一次开源java spring快速开发平台项目RuoYi部署的记录
java·spring·开源
硕风和炜1 小时前
【LeetCode: 743. 网络延迟时间 + Dijkstra】
java·算法·leetcode·面试·dijkstra·最短路径