博客
关于我
业务逻辑层缓存应该设计
阅读量: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 request模块
查看>>
Python requirements.txt的使用方法
查看>>
Python REST(Web 服务)框架的推荐?
查看>>
Python rsa 加密
查看>>
Python RSA操作
查看>>
Python轻松实现统计学中重要的相关性分析
查看>>
Python scrapy 常见问题及解决 【遇到的坑】
查看>>
Python Seborn热图数据的动态更新
查看>>
Python Seborn绘制空白直方图
查看>>
Python Selenium - 获取href值
查看>>
Python Selenium实现自动化测试及Chrome驱动使用!
查看>>
Python Selenium搭建UI自动化测试框架
查看>>
Python Selenium模块详解
查看>>
Python selenium爬取影评生成词云图
查看>>
python selenium自动化测试报告
查看>>
Python selenium自动化测试框架实战 —— 登录测试案例
查看>>
Python Selenium设计模式 —— POM
查看>>
Python Serial:如何使用 read 或 readline 函数一次读取多个字符
查看>>
Python set([]) 如何检查两个对象是否相等?一个对象需要定义哪些方法来自定义它?
查看>>
Python setup.py:数据文件无法复制目录:不存在或不是常规文件
查看>>