分层思想的一个核心就是部件化,各个层之间是相互独立的,每一层可以随便抽取换成一个其他语言的版本,但只要与相应的接口吻合就行。
我用的三层架构大致是这样的,基本的三层就不说了,然后分别为业务逻辑层和数据访问层定义一个接口,由具体的那个层来实现,问题产生了,由谁来指定程序使用哪个具体的对象来实现相应接口?
为解决这个问题,我应用的是抽象工厂模式。分别为业务逻辑层和数据访问层添加一个抽象工厂。具体架构还是看下图吧。
这里的Utility是一个工具类,在下文中会提到。
学过设计模式的人都应该听过反射技术,但是一个系统中用到的类很多,需要对每一个类进行实例化,如果仅利用抽象工厂+反射模式,重复的代码比较多,如果哪一天整个DAL层发生变更,那么就要在代码中修改每一个用到的地方,不仅不容易维护,而且还很容易出错,未解决这个问题,对程序作了一个优化——用到依赖注入。还是看看代码吧。
1、先看看依赖注入的容器:这里我把这个注入容器放到了工具类中,刚开始学习设计模式,不知道是否合理,欢迎高手们指点。
- Imports System.Configuration
- Imports System.Reflection
- Public Class DependencyInjector
- ''' <summary>
- ''' 利用反射机制,取得数据访问层对象
- ''' </summary>
- ''' <param name="className">传入数据访问层中要实例化的类的名称</param>
- ''' <returns>指定的数据访问层的类</returns>
- ''' <remarks></remarks>
- Function GetDALObject(ByVal className As String) Object
- Dim dal Object
- Dim dalName String
- Dim fullClassName String
- Dim dalObj '通过配置文件的指定要应用的DAL层
- dal = System.Configuration.ConfigurationManager.AppSettings("DAL")
- 'dalName就是常说的用用程序的名称
- dalName = dal.ToString
- '命名空间+类的名称,指明要实例化的类的路径
- fullClassName = dalName + "." + className
- '通过反射,取得数据访问层对象
- dalObj = Assembly.Load(dalName).CreateInstance(fullClassName)
- '返回指定的对象
- Return dalObj
- End Function
- '''取得指定业务逻辑层的指定类
- ''' <param name="className">要应用的业务逻辑层的具体类的名称</param>
- ''' <returns>指定的业务逻辑层的类(对象)</returns>
- Function GetBLLObject(Dim bll Dim bllName Dim bllObj '从配置文件中读取业务逻辑名称
- bll = System.Configuration.ConfigurationManager.AppSettings("BLL")
- bllName = bll.ToString
- fullClassName = bllName + "." + className
- '利用反射取得业务逻辑层对象
- bllObj = Assembly.Load(bllName).CreateInstance(fullClassName)
- Return bllObj
- Function
- Class
2、相关配置文件:
- <appSettings>
- add key="connStr" value="Persist Security Info=true;Data Source=*****;Initial Catalog=Charge_Sys_SelfDesign;User ID=sa;PWD=****;" />
- add key="DAL" value="DAL" />
- add key="BLL" value="BLL" />
- </>