博客
关于我
业务逻辑层缓存应该设计
阅读量: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/

你可能感兴趣的文章
Objective-C实现大小端数转换(附完整源码)
查看>>
Objective-C实现大根堆(附完整源码)
查看>>
Objective-C实现奇偶检验码(附完整源码)
查看>>
Objective-C实现奇偶转置排序算法(附完整源码)
查看>>
Objective-C实现奇异值分解SVD(附完整源码)
查看>>
Objective-C实现奎因-麦克拉斯基算法(附完整源码)
查看>>
Objective-C实现子集总和算法(附完整源码)
查看>>
Objective-C实现子集数的总和等于给定的数算法(附完整源码)
查看>>
Objective-C实现字符串autocomplete using trie(使用 trie 自动完成)算法(附完整源码)
查看>>
Objective-C实现字符串boyer moore search博耶摩尔搜索算法(附完整源码)
查看>>
Objective-C实现字符串IP地址转DWORD地址(附完整源码)
查看>>
Objective-C实现字符串jaro winkler算法(附完整源码)
查看>>
Objective-C实现字符串levenshtein distance编辑距离算法(附完整源码)
查看>>
Objective-C实现字符串manacher马拉车算法(附完整源码)
查看>>
Objective-C实现字符串split函数功能算法(附完整源码)
查看>>
Objective-C实现字符串wildcard pattern matching通配符模式匹配算法(附完整源码)
查看>>
Objective-C实现字符串word patterns单词模式算法(附完整源码)
查看>>
Objective-C实现字符串Z 函数或 Z 算法(附完整源码)
查看>>
Objective-C实现字符串加解密(附完整源码)
查看>>
Objective-C实现字符串反转(附完整源码)
查看>>