面向接口编程在.N E T三层结构系统中的应用研究
2013-09-18刘军华
刘军华
(湖南邮电职业技术学院,湖南长沙410015)
Microsoft.Net Framework是微软推出的一套新一代开发平台。ASP.NET作为其中的一部分,其最大的优点除了编译执行速度快外,还有一点就是页面和代码分离的编写方式[1]。这就使得基于.NET平台可以快速方便地部署B/S三层架构Web应用程序。然而,传统的三层架构之间一般是表示层引用业务逻辑层,业务逻辑层再引用数据访问层。另外,在实际项目开发过程中,由于客户需求的不确定性,很有可能会因为自身需要而经常变化,这就使得程序员必须不停地改写现有的业务代码。这样,就形成三个层次之间的依赖性太高,不便于实现层与层之间的可替换,而且还加大了软件后期测试和维护的难度,影响系统本身的稳定性。为了降低三层结构系统中层与层之间的耦合度,增强系统的可拓展和可移植性,本文提出一种面向接口的编程思想应用于三层架构当中,以实现层次之间的无缝结合,保证系统的通用性、标准化和数据库的可移植性。
1 接口
1.1 定义
外界观察任何一个对象,最主要关注对象提供了哪些服务。至于这些服务的功能是如何在对象内部实现的,外界并不关心。对象所提供的服务就是对象所提供的操作,而操作就是方法。因此,对象中所有外界能使用方法集合,构成了对象与外界进行交互的“界面”,即接口。简单地讲,接口就是一些方法特征的集合,但不提供实现方式。下面以消息显示功能为例说明接口的定义:
public interface ITest{ //定义接口ITest
void show(string strMsg);//定义接口成员方法show
}
以上是定义一个测试接口,相当于在程序中设置一个约定的业务规范。
1.2 用法
由于接口只提供方法定义,不提供方法实现。一般交由继承该接口的类去实现,而一个接口可以被多个类继承,因此,每一个类可以自由决定其实现方式的细节,即是以不同的方式实现同一接口中的同名方法,使其具有完全不同的表现行为[2]。识别接口的代码可以利用类的对象,因为接口对于这些对象是相同的。.NET允许充分利用“一个接口,多个方法”的多态性。如:
public class A:ITest
{public void show(string strMsg) {
Console.WriteLine(strMsg+“明天更美好!”);
}
}
public class B:ITest
{public void show(string strMsg) {
Console.WriteLine(strMsg+“明天更辉煌!”);
}
}
A、B类都实现了ITest的规范,但表示行为完全不同。使用.NET接口标识类型,程序运行时,将根据实际创建的对象类型调用相应的方法实现。public class Program
{
static void Main(string[]args) {
#region没有用接口时的一种做法
//A a=new A();
//a.show(“邮电事业”);
//B b=new B();
//b.show(“邮电事业”);
#endregion
#region有用接口时的一种做法
ITest test=new A();
test.show(“邮电事业”);
test=new B();
test.show(“邮电事业”);
#endregion
}
}
通过以上代码可以清楚地看出,没有使用接口时,编译时可以通过方法调用对象的不同区分出调用哪个类中的show方法;而使用了接口之后,因为方法调用对象是同一个,所以必须在程序运行时,通过创建对象的类型来决定调用哪个类中的show方法。正因为接口的这一特点,为多层结构之间的动态访问成为现实,进一步提高了程序的灵活性。
2 三层体系结构
2.1 传统三层结构的简介
传统的三层架构包括表示层、业务逻辑层和数据访问层。示意图如图1所示。这样做的目的就为了实现软件的“高内聚,低耦合”的架构思想。每个层实现应用程序一个方面的逻辑功能,通过层与层之间的交互,形成应用程序体系架构,从而实现适应于企业级应用的、功能复杂的应用程序[3]。
图1 三层架构示意图
1)表示层:表示位于最外层,是离用户最近的层。主要完成了两个任务:一是获取数据并显示,将从业务逻辑层中动态获取的数据以适当的形式显示给用户;二是接收数据并传递,将用户从界面输入的数据传入业务逻辑层进行下一步的处理。
2)业务逻辑层:逻辑层是整个分层模型的中间层。主要负责处理所有来自表示层的用户请求,并根据具体应用将用户请求进行组合,形成一种业务规则转换为对数据访问层的请求;同时,将数据访问层返回的结果提交给表示层。
3)数据访问层:数据访问层是整个分层体系的最底层。主要实现对数据库进行增删查改操作。为业务逻辑层提供数据服务,根据业务逻辑层的要求从数据库中提取数据或者修改数据库中的数据。由于访问数据库是系统中频繁发生而且最消耗资源的操作,所以在这一层要对数据库访问进行优化,提高系统的性能和可靠性[4]。
2.2 传统三层结构的解决方案
在传统的三层体系结构中,表示层依赖业务逻辑层,业务逻辑层依赖数据访问层。例如,单击表示层界面中某一测试按钮,就将数据库商品表中的最新10条记录读取并显示在网格控件中。各层次参考代码如下:
1) WEB表示层:protected BLL.Products pr=new BLL.Products();
protected void btnTest_Click(object sender,EventArgs e)
{ //获取最新商品,显示到newProducts控件中
DataTable dt=pr.getNewProducts();
newProducts.DataSource=dt;
newProducts.DataBind();
}
2)BLL业务层代码片断:class Products
{
public DataTable getNewProducts(){
string Sqlstr=”select top 10*from products order by id desc”;
DataTable dt=DBUtility.SQLHelper.ExecuteDT(Sqlstr);
return dt;
}
}
3)DBUtility数据访问层代码:class SQLHelper
{
public static DataTable ExecuteDT (string Sqlstr)
{
sring ConnStr=SQLHelper.GetSqlConnection();
using (sqlConnection conn=new sqlConnection(ConnStr)) {
sqlDataAdapter da=new sqlDataAdapter(Sqlstr,conn);
DataTable dt=new DataTable();
conn.Open();
da.Fill(dt);
return dt;
}
}
}
通过对上述代码分析,可以看出层次之间的深度依赖,业务逻辑层直接调用数据访问层的ExecuteDT方法,这时,如果想换一种方式实现数据访问层,那么就必须修改业务逻辑层所有相关代码。不利于程序的测试、维护以及进一步扩展。
2.3 应用接口的三层结构解决方案
针对上述传统三层体系结构出现的问题,以及系统中许多应用都是由两个或更多的类通过彼此合作来实现业务逻辑,这使得每个对象都需要与和它合作的对象的引用,如果这个获取过程要靠自身实现,那么将导致代码高度耦合且难以测试。此时,引入了面向接口编程思想,使上层类不能具体依赖于下层类,而只依赖于下层提供的一个接口。为此,需要在传统三层结构的基础上,再添加三个逻辑层,分别是接口层、接口实现层以及工厂层。改进后的多层体系结构如图2所示。
图2 多层体系结构图
其中,业务逻辑层不再仅依赖于某一具体数据访问层,而是利用.NET中的依赖注入机制以及创建工厂类的方式来动态加载实现。下面给出各层的引用关系及功能介绍。
1)WEB表示层:该层基本保持不变,与业务逻辑层之间采用紧耦合。另外,需要在该层中的Web.config文件的
2)BLL业务逻辑层:该层将不再直接引用数据访问层,而是引用IDAL接口层和Factory工厂层。通过工厂层得到程序集指定类的实例并决定调用哪个数据访问层的数据操作方法。
3)IDAL接口层:该层的设置目的是使业务逻辑与接口实现层(数据访问层)的完全分离,一般仅需引用实体层。该层与具体的数据访问层无关,主要定义了数据访问层必须要实现的业务逻辑操作集。即是规定系统必须要实现的所有业务功能。
4)Factory工厂层:该层引用接口层,主要是完成创建并返回所有的程序集实例。通过读取web.config里设置的程序集名称,加载类的实例,返回给BLL业务逻辑层使用。
5) SQLServerDAL接口实现层:又称 SQL Server数据访问层。引用 Model和IDAL,且继承IDAL中的接口,主要是实现接口层IDAL中定义的方法。为了支持更多数据库还可以有OracleDAL、AccessDAL的实现,具体使用哪个由Factory工厂层决定。
6)DBUtility数据库操作层:该层无需引用其它层。它是对ADO.NET数据访问封装的一个组件类库,类库中可以包括多个数据库的访问类,如SQLServerHelper、OracleHelper等,一般是为上层的具体某一数据访问层提供通用的数据库操作方法。
7) Entity实体层:该层无需引用其它层。主要担负着数据在软件架构各层次及模块间传递的职责。自始至终贯穿于整个软件框架各层,它是现实生活中实体特性在计算机中的表示,其基本映射策略是每个实体类对应一个数据库表,且类成员往往与该数据表的表结构一致[5]。
3 结束语
基于ASP.NET三层架构的软件开发已经成为一种流行的开发模式,然而,传统的三层架构系统各层次之间存在紧耦合问题,针对这一问题,论文提出了一种面向接口编程思想应用于三层架构当中,充分利用.NET中的依赖注入机制以及创建工厂类的方式来动态加载实现。实践证明,应用接口的多层架构的开发模式不仅可以降低层次间的依赖关系,有利于标准化和开发人员工作的分配。还使得程序的灵活性更高,有利于各层逻辑的复用以及软件后期维护和扩展。
[1]宋磊.基于ASP.NET的三层结构实现方法研究[J].黑龙江科技信息,2010(15).
[2]徐枫.ASP.NET三层架构体系分析与应用[J].数据技术与应用,2011(8):109-110.
[3]华铨平.抽象工厂设计模式在三层结构开发中的应用[J].大庆石油学院学报,2009,3(33).
[4]刘军华,张丽敏.基于数据字典的实体类的设计与实现[J].湖南工业职业技术学院学报,2012(5).