项目总结——谈谈封装(抽象工厂+反射+缓存机制)
今天想给大家说的也是刚刚结束的项目中遇到的一个优秀的封装,当然也要拿出来给大家分享了。
背景交代,我们的项目是一个BS的项目,基本的架构是工厂模式三层,所以就用到了抽象工厂加反射,今天要给大家讲的也就是这块的东西——使用缓存文件。
背景交代完毕。
一、首先说一下什么是缓存文件?
msdn上说:
通常,应用程序可以将那些频繁访问的数据,以及那些需要大量处理时间来创建的数据存储在内存中,从而提高性能。例如,如果应用程序使用复杂的逻辑来处理大量数据,然后再将数据作为用户频繁访问的报表返回,避免在用户每次请求数据时重新创建报表可以提高效率。同样,如果应用程序包含一个处理复杂数据但不需要经常更新的页,则在每次请求时服务器都重新创建该页会使工作效率低下。
二、为什么要使用缓存?
ASP.NET为您提供了一个强大的、便于使用的缓存机制,用于将需要大量服务器资源来创建的对象存储在内存中。缓存这些类型的资源会大大改进应用程序的性能。
缓存(Cache)是一种用空间换取时间的技术,存在于计算机中很多地方,用来将一些慢速设备中的常用数据保存在快速设备中,取数据的时候直接从快速设备中取。比如CPU二级缓存、内存、windows文件读取缓存。缓存是改进网站性能的第一个手段,就像索引是改进数据库性能的第一个手段一样
三、如何使用缓存?
缓存是由 Cache 类实现的;缓存实例是每个应用程序专用的。缓存生存期依赖于应用程序的生存期;重新启动应用程序后,将重新创建 Cache 对象。
设计 Cache 类是为了便于使用。您可以将项放置在 Cache 中,并在以后使用简单的键/值对来检索这些项。
说的上面的这些当然都是官方的语言,下面给大家介绍我的这个项目中是如何使用缓存文件的:
四、说用在哪?
上面说过,“将需要大量服务器资源来创建的对象存储在内存中”大家想想这个B/S程序,一个访问者的一次访问和一万个访问者的一百万次访问,给服务器带来压力的对比就很容易体会缓存的好处了。每一次的访问请求数据库都需要执行耗费资源的反射机制来动态的创建D层的实例。如果使用缓存把第一次创建的实例保存起来,每一次访问都把已经存在创建好的实例拿来用,对服务器来说就节省了好大的一笔开销。而且我们需要保存的也就是D层中屈指可数的几个类。
说的太多了,上代码:
从工厂某一个方法开始:
- /// <summary>
- /// 创建SqlMaintainRecordInfo数据层接口。维修日志表
- /// </summary>
- public static IDAL.IMaintainRecordInfo CreateT_MaintainRecordInfo()
- {
- string ClassNamespace = AssemblyPath +".SqlMaintainRecordInfo";
- object objType=CreateObject(AssemblyPath,ClassNamespace);
- return (IDAL.IMaintainRecordInfo)objType;
- }
/// <summary> /// 创建SqlMaintainRecordInfo数据层接口。维修日志表
/// </summary> public static IDAL.IMaintainRecordInfo CreateT_MaintainRecordInfo() { string ClassNamespace = AssemblyPath +".SqlMaintainRecordInfo"; object objType=CreateObject(AssemblyPath,ClassNamespace); return (IDAL.IMaintainRecordInfo)objType; }
和以往直接使用反射机制不同,这个调用CreateObject函数:
- //使用缓存
- private static object CreateObject(string AssemblyPath,string classNamespace)
- {
- object objType = DataCache.GetCache(classNamespace);
- if (objType == null)
- {
- try
- {
- objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace);
- DataCache.SetCache(classNamespace, objType);// 写入缓存
- }
- catch(System.Exception ex)
- {
- string str=ex.Message;// 记录错误日志
- }
- }
- return objType;
- }
//使用缓存
private static object CreateObject(string AssemblyPath,string classNamespace) { object objType = DataCache.GetCache(classNamespace); if (objType == null) { try { objType = Assembly.Load(AssemblyPath).CreateInstance(classNamespace); DataCache.SetCache(classNamespace, objType);// 写入缓存 } catch(System.Exception ex) { string str=ex.Message;// 记录错误日志 } } return objType; }
这个大家也能看到,创建前需要先判断,需要创建的D层类在缓存中是否已经存在,如果如果存在直接返回,如果不存在使用反射机制创建,然后保存,方便以后使用。
其中的DataCache.GetCache和DataCache.SetCache:
- /// <summary>
- /// 缓存操作类
- /// </summary>
- public class DataCache
- {
- /// <summary>
- /// 获取当前应用程序指定CacheKey的Cache值
- /// </summary>
- public static object GetCache(string CacheKey)
- {
- System.Web.Caching.Cache objCache = HttpRuntime.Cache;
- return objCache[CacheKey];
- }
- /// <summary>
- /// 设置当前应用程序指定CacheKey的Cache值
- /// </summary>
- public static void SetCache(string CacheKey, object objObject)
- {
- System.Web.Caching.Cache objCache = HttpRuntime.Cache;
- objCache.Insert(CacheKey, objObject);
- }
- }
/// <summary> /// 缓存操作类--韩义 /// </summary> public class DataCache { /// <summary> /// 获取当前应用程序指定CacheKey的Cache值
/// </summary> public static object GetCache(string CacheKey) { System.Web.Caching.Cache objCache = HttpRuntime.Cache; return objCache[CacheKey]; } /// <summary> /// 设置当前应用程序指定CacheKey的Cache值
/// </summary> public static void SetCache(string CacheKey, object objObject) { System.Web.Caching.Cache objCache = HttpRuntime.Cache; objCache.Insert(CacheKey, objObject); } }
看到这个我想大家应该会想这里确实也可以使用单例模式--如果有的话返回,没有的话创建返回。
五、这里又为什么不用单例模式。
大家考虑一下单例的实现,是需要定义一个静态的变量用于保存的。这样我们在判断的时候就需要知道具体的存放想要创建的类的变量名(好像有点饶口,大家好好理解)这样我们的判断方法就不能很好的封装。
六、总结:
设计 Cache 类是为了便于使用。您可以将项放置在 Cache 中,并在以后使用简单的键/值对来检索这些项。在WebForm中主要是为了减轻Web服务器压力,在客户端提供了缓存机制,当用户访问的网页内容无变化的请求时就会调用缓存中的内容,这样一来减轻了服务器压力,避免无必要的重复操作,二来使用户网页浏览速度加快,用户体验更好。WebForm是“瘦客户端”。