博客
关于我
业务逻辑层缓存应该设计
阅读量:453 次
发布时间:2019-03-06

本文共 3176 字,大约阅读时间需要 10 分钟。

在业务制定时很少会切入缓存设计,这通常是一种过渡设计。毕竟,在指标不明确的情况下,这属于一种过渡设计。然而,缓存切入有很多手段,在很多时候直接在WEB进行页面缓存就能带来非常高的收益效果。缓存是一种横向的数据处理应用,通常在设计中引入AOP、ICO等应用组件都可以后期切入添加。但在没有比较丰富的经验的情况下引入AOP、ICO会直接增加应用的复杂度和风险。因此,在设计时引入一种简单的缓存方式,而不带来复杂的工作成本,是一种更优的选择。

一个简单示例

以下是一个不考虑缓存应用的常见开发方式:

public class BlogService : Interfaces.IBlogService{    public IList
List(string category, int size, int index, out int pages) { Expression exp = new Expression(); if (!string.IsNullOrEmpty(category)) exp &= Blog.iD == BlogLinkCategory.blog[BlogLinkCategory.category == category]; int count = exp.Count(); pages = count / size; if (count % size > 0) pages++; return exp.List(new Region(index, size), Blog.createTime.Desc); } public IList
ListCategories() { return new Expression().List(); } public Blog Get(string id) { return (Blog.iD == id).ListFirst(); }}

简单加入缓存

List方法为例,加入缓存处理方式:

public IList
List(string category, int size, int index, out int pages){ var result = redis.Get("key"); if (result == null) { Expression exp = new Expression(); if (!string.IsNullOrEmpty(category)) exp &= Blog.iD == BlogLinkCategory.blog[BlogLinkCategory.category == category]; int count = exp.Count(); pages = count / size; if (count % size > 0) pages++; result = exp.List(new Region(index, size), Blog.createTime.Desc); redis.Set("key", result); } return result;}

这种方式在开发中比较常见,但在前期阶段没有性能要求时会增加较大的工作量。此外,缓存产品的偶合性可能达不到理想的效果,因为开发人员还需要学习具体缓存产品的API。

缓存实现的解偶

可以在设计时制定一个简单的缓存存取接口:

public interface ICached{    T Get(Func
); void Set(string key, object data);}

在设计时引入到接口定义中:

public interface IBlogService{    IList
List(string category, int size, int index, out int pages); Blog Get(string id); Blog Save(string id, string title, string keywords, string data, params string[] categories); IList
ListCategories(); ICached Cached { get; set; }}

通过这种方式,可以在逻辑层或其他层面引入缓存设计,而不会对整个代码带来较大的复杂度变化。刚开始可以引用一个完全不做任何实现的ICached,待有需要时再更换具体实现。

缓存应用简化

可以在接口中定义一些简单的委托参数,使得缓存在应用时的复用度更高:

public interface ICached{    T Get(Func
); void Set(string key, object data);}

在编写逻辑时就可以简化为:

public IList
List(string category, int size, int index, out int pages){ var cached = Cached.Get(() => { var result = new ExpandoObject(); Expression exp = new Expression(); if (!string.IsNullOrEmpty(category)) exp &= Blog.iD == BlogLinkCategory.blog[BlogLinkCategory.category == category]; int count = exp.Count(); result.Pages = count / size; if (count % size > 0) result.Pages++; result.Blogs = exp.List(new Region(index, size), Blog.createTime.Desc); return result; }, "ListKey"); pages = cached.Pages; return cached.Blogs;}

这种方式的原理很简单:Get方法内部会检查是否有对应的key,如果存在则直接返回缓存数据,否则执行Func方法获取数据并设置到缓存中。这种方式适用于处理一些条件和分页返回等场景,代码量相对较少。

总结

通过这种设计方式,在逻辑层或其他层面引入缓存设计不会对整个代码带来较大的复杂度变化。刚开始可以引用一个完全不做任何实现的ICached,待有需要时再更换具体实现。这种设计方式的优点在于降低了开发人员对缓存产品依赖的程度,但在实际业务场景中可能需要更多的参数和配置。总之,通过这种方式可以在不影响现有功能的前提下,灵活地引入缓存设计。

转载地址:http://gzxfz.baihongyu.com/

你可能感兴趣的文章
Python furl库:一键搞定复杂URL操作
查看>>
Python GC 也会关闭文件吗?
查看>>
python gen_key.py 报错 提示找不到OpenSSL lib
查看>>
python getattrribute_Python学习——面向对象高级之反射
查看>>
Python进阶语法:字典推导式
查看>>
python gil_Python中GIL的使用详解
查看>>
python glob.glob使用
查看>>
python glob的安装和使用
查看>>
Python google drive API 下载,文件在哪里?
查看>>
Python GPS 模块:读取最新的 GPS 数据
查看>>
python grpc入门
查看>>
python gRPC测试helloworld
查看>>
python gRPC简单示例
查看>>
Python GUI 开发:全面指南
查看>>
Python hashlib模块
查看>>
python hashlib模块
查看>>
python if,循环的练习
查看>>
Python in open course (week3)
查看>>
Python IO编程
查看>>
python join split
查看>>