我们设计的分层架构,层与层之间应该是松散耦合的。因为是单向单一调用,所以,这里的“松散耦合”实际是指上层类不能具体依赖于下层类,而应该依赖于下层提供的一个接口。这样,上层类不能直接实例化下层中的类,而只持有接口,至于接口所指变量最终究竟是哪一个类,则由依赖注入机制决定。
之所以这样做,是为了实现层与层之间的“可替换”式设计,例如,现在需要换一种方式实现数据访问层,只要这个实现遵循了前面定义的数据访问层接口,业务逻辑层和表示层不需要做任何改动,只需要改一下配置文件系统即可正常运行。另外,基于这种结构的系统,还可以实现并行开发。即不同开发人员可以专注于自己的层次,只有接口被定义好了,开发出来的东西就可以无缝连接。
在J2EE平台上,主要使用Spring框架实现依赖注入。这里,我们将自己做一个依赖注入容器。
依赖注入的理论基础是Abstract Factory设计模式,这里结合具体实例简单介绍一下。
封装依赖注入代码
因为很多依赖注入代码非常相似,为了减少重复性代码,我们将可复用的代码先封装在一个类中。具体代码如下(这个类放在Factory工程下):
|
using System; using System.Configuration; using System.Reflection; using System.Web; using System.Web.Caching; using NGuestBook.Utility;
namespace NGuestBook.Factory { /**//// <summary> /// 依赖注入提供者 /// 使用反射机制实现 /// </summary> public sealed class DependencyInjector { /**//// <summary> /// 取得数据访问层对象 /// 首先检查缓存中是否存在,如果不存在,则利用反射机制返回对象 /// </summary> /// <param name="className">数据访问类名称</param> /// <returns>数据访问层对象</returns> public static object GetDALObject(string className) { /**//// <summary> /// 取得数据访问层名称,首先检查缓存,不存在则到配置文件中读取 /// 缓存依赖项为Web.Config文件 /// </summary> object dal = CacheAccess.GetFromCache("DAL"); if (dal == null) { CacheDependency fileDependency = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config")); dal = ConfigurationManager.AppSettings["DAL"]; CacheAccess.SaveToCache("DAL", dal, fileDependency); }
/**//// <summary> /// 取得数据访问层对象 /// </summary> string dalName = (string)dal; string fullClassName = dalName + "." + className; object dalObject = CacheAccess.GetFromCache(className); if (dalObject == null) { CacheDependency fileDependency = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config")); dalObject = Assembly.Load(dalName).CreateInstance(fullClassName); CacheAccess.SaveToCache(className, dalObject, fileDependency); }
return dalObject; }
/**//// <summary> /// 取得业务逻辑层对象 /// 首先检查缓存中是否存在,如果不存在,则利用反射机制返回对象 /// </summary> /// <param name="className">业务逻辑类名称</param> /// <returns>业务逻辑层对象</returns> public static object GetBLLObject(string className) { /**//// <summary> /// 取得业务逻辑层名称,首先检查缓存,不存在则到配置文件中读取 /// 缓存依赖项为Web.Config文件 /// </summary> object bll = CacheAccess.GetFromCache("BLL"); if (bll == null) { CacheDependency fileDependency = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config")); bll = ConfigurationManager.AppSettings["BLL"]; CacheAccess.SaveToCache("BLL", bll, fileDependency); }
/**//// <summary> /// 取得业务逻辑层对象 /// </summary> string bllName = (string)bll; string fullClassName = bllName + "." + className; object bllObject = CacheAccess.GetFromCache(className); if (bllObject == null) { CacheDependency fileDependency = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config")); bllObject = Assembly.Load(bllName).CreateInstance(fullClassName); CacheAccess.SaveToCache(className, bllObject, fileDependency); }
return bllObject; } } }
|
实现工厂
下面使用两个辅助类,实现数据访问层工厂和业务逻辑层工厂。
|
using System; using NGuestBook.IDAL;
namespace NGuestBook.Factory { /**//// <summary> /// 数据访问层工厂,用于获取相应的数据访问层对象 /// 使用Abstract Factory设计模式+Facace设计模式+反射机制+缓存机制设计 /// </summary> public sealed class DALFactory { /**//// <summary> /// 获取管理员数据访问层对象 /// </summary> /// <returns>管理员数据访问层对象</returns> public static IAdminDAL CreateAdminDAL() { return (IAdminDAL)DependencyInjector.GetDALObject("AdminDAL"); } /**//// <summary> /// 获取留言数据访问层对象 /// </summary> /// <returns>留言数据访问层对象</returns> public static IMessageDAL CreateMessageDAL() { return (IMessageDAL)DependencyInjector.GetDALObject("MessageDAL"); }
/**//// <summary> /// 获取评论数据访问层对象 /// </summary> /// <returns>评论数据访问层对象</returns> public static ICommentDAL CreateCommentDAL() { return (ICommentDAL)DependencyInjector.GetDALObject("CommentDAL"); } } }
|
|
using System; using NGuestBook.IBLL;
namespace NGuestBook.Factory { /**//// <summary> /// 业务逻辑层工厂,用于获取相应的业务逻辑层对象 /// 使用Abstract Factory设计模式+Facace设计模式+反射机制+缓存机制设计 /// </summary> public sealed class BLLFactory { /**//// <summary> /// 获取管理员业务逻辑层对象 /// </summary> /// <returns>管理员业务逻辑层对象</returns> public static IAdminBLL CreateAdminBLL() { return (IAdminBLL)DependencyInjector.GetBLLObject("AdminBLL"); }
/**//// <summary> /// 获取留言业务逻辑层对象 /// </summary> /// <returns>留言业务逻辑层对象</returns> public static IMessageBLL CreateMessageBLL() { return (IMessageBLL)DependencyInjector.GetBLLObject("MessageBLL"); }
/**//// <summary> /// 获取评论业务逻辑层对象 /// </summary> /// <returns>评论业务逻辑层对象</returns> public static ICommentBLL CreateCommentBLL() { return (ICommentBLL)DependencyInjector.GetBLLObject("CommentBLL"); } } }
|