在用"三层架构"思想做机房收费系统的时候,感觉最经典的三层架构图就是下面这个图了。
你有没有发现按照上面这副图做的话,BLL层跟DAL层联系太紧密了,这样实现的系统,就相当于把数据库写死了,想更换别的数据库可不是件简单的事,于是我们就想到了要在DAL层加上接口+"抽象工厂设计模式"。于是就出现了下面这副图
在这里谈谈我理解的接口所具有的作用,说的不对的地方,还请高手指点!
接口是面向对象方法最重要的特性之一。现阶段我理解的接口具有的作用有两点:一是契约、二是解耦。
一.契约,即约定
在IDAL层的各个接口层,规定好每个接口里实现什么方法,在DAL层的类继承某一接口时就必须实现对应接口里的所有方法,少一个都不行。一个接口可以被多个类继承,一个类也可以同时继承多个接口。
例如,IDAL层有一个访问基本数据表的接口,代码如下:
'''
''' 这是接口层,用于访问“基本数据表”的一个接口
'''
'''
Public Interface IBaseData
'''
''' 取出"基本数据表"中数据,放到一个DataTable表中
'''
''' 数据表(DataTable)
'''
Function GetBaseDataInfo() As System.Data.DataTable
'''
''' 更新基本数据表中的信息
'''
''' 参数为"基本数据"实体
''' 是否更新成功
'''
Function UpdateBaseData(ByVal BaseData As Entity.BaseDataSet) As Boolean
End Interface
DAL层的类继承上面这个接口时,就必须实现里面的两个方法,少一个都不行,这样起到一个约束。实现代码如下:
'''
''' 这是数据访问层"基本数据信息"类
'''
'''
Public Class SqlBaseDataDao
Implements IDAL.IBaseData
'''
''' 取出"基本数据表"中数据,放到一个DataTable表中
'''
''' 数据表(DataTable)
'''
Public Function GetBaseDataInfo() As System.Data.DataTable Implements IDAL.IBaseData.GetBaseDataInfo
'设置sql语句
Dim strSql As String = "select * form BaseDataSet"
'实例化一个SqlHelper
Dim ExecSqlHelper As New SqlServerHelper.SqlHelper
'执行无参查询函数,返回"基本数据"数据表
Return ExecSqlHelper.ExeQueryNoParameters(strSql, CommandType.Text)
End Function
'''
''' 更新基本数据表中的信息
'''
''' 参数为"基本数据"实体
''' 是否更新成功
'''
Public Function UpdateBaseData(ByVal BaseData As Entity.BaseDataSet) As Boolean Implements IDAL.IBaseData.UpdateBaseData
'设置sql语句
Dim strSql As String = "update BaseDataSet set Rate=@Rate,TmpRate=@TmpRate," _
& "UniTime=@UniTime,LeastTime=@LeastTime," _
& "PrePareTime=@PrePareTime,LimitCash=@LimitCash,Operatorr=@Operatorr)"
'实例化一个SqlHelper
Dim ExecSqlHelper As New SqlServerHelper.SqlHelper
'创建命令参数数组
Dim SqlParam(6) As SqlParameter
'给命令参数数组赋值
SqlParam(0) = ExecSqlHelper.AddSqlParameter("Rate", SqlDbType.Float, CStr(BaseData.Rate))
SqlParam(1) = ExecSqlHelper.AddSqlParameter("TmpRate", SqlDbType.Float, CStr(BaseData.TmpRate))
SqlParam(2) = ExecSqlHelper.AddSqlParameter("UniTime", SqlDbType.Date, CStr(BaseData.UniTime))
SqlParam(3) = ExecSqlHelper.AddSqlParameter("LeastTime", SqlDbType.Date, CStr(BaseData.LeastTime))
SqlParam(4) = ExecSqlHelper.AddSqlParameter("PrePareTime", SqlDbType.Date, CStr(BaseData.PrePareTime))
SqlParam(5) = ExecSqlHelper.AddSqlParameter("LimitCash", SqlDbType.Float, CStr(BaseData.LimitCash))
SqlParam(6) = ExecSqlHelper.AddSqlParameter("Operatorr", SqlDbType.VarChar, CStr(BaseData.Operatorr))
'执行修改基本数据命令,返回是否成功
Return ExecSqlHelper.ExeNotQueryWithParameters(strSql, CommandType.Text, SqlParam)
End Function
End Class
二.解耦作用
使用第一幅图的设计,我们开发"机房收费系统"用SQL Server数据库,如果需要一个Access的数据库orMySql的数据库,这时需要把涉及数据操作的逻辑代码(BLL层、DAL层)全部改写,对不?
使用第二幅图,我们在DAL层加了IDAL接口,IDAL接口就作为一层。首先,定义逻辑操作接口,涉及数据操作的类(DAL层的类)继承该接口实现,在BLL逻辑层调用的时候,面对的是接口编程,BLL层直接声明接口,将操作对象直接转换为接口类型。 这时候,如果换用不同的数据库,只要改动DAL层的方法就可以了,BLL层就不用改了。面对接口编程也就去除了BLL层与DAL层的耦合。