基于.NET平台的分层架构实战_第1页
基于.NET平台的分层架构实战_第2页
基于.NET平台的分层架构实战_第3页
基于.NET平台的分层架构实战_第4页
基于.NET平台的分层架构实战_第5页
已阅读5页,还剩80页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、基于.NET平台的分层架构实战(一)综述(本文来自 晚12:34整理完)通过浏览博客园的文章发现,很多朋友对分层架构特别感兴趣,刚好我刚做完的毕业设计就是专门研究.NET平台上分层架构的(题目叫“基于.NET平台的分层架构与设计模式应用研究”)。通过做这篇论文,我对分层架构有了一定的了解,所以,就萌发了想写一个文章系列,详述一下分层架构。然而,论文的理论性太强,不适合在网上发布,尤其不适合初学者理解,所以,我想在这个文章系列中,少讲理论,而是通过做一个完整的案例来讨论分层架构的基本方法,这样会直观很多。希望在这个文章系列的写作过程中,能和朋友们一起学习,一起进步。 为了让朋友们把主要精力放在理

2、解分层架构而不是案例本身,我准备选择一个相对简单的留言本系统作为Demo,这个系统的名字就叫做NGuestBook。初步计划将这个文章系列分为以下几篇:1.综述2.系统需求分析及数据库设计3.架构概要设计4.实体类的实现5.接口的设计与实现6.依赖注入及IoC的设计与实现7.数据访问层的第一种实现Access+动态生成SQL语言8.数据访问层的第二种实现SQLServer+存储过程9.数据访问层的第三种实现基于NBear框架的ORM实现10.业务逻辑层的实现11.表示层的实现12.使用ASP.NET AJAX框架对表示层进行改进13.总结 当然,以上只是初步计划,在写文章的过程中可能会根据具体

3、情况适当调整,但是内容大体就是这些。 这个文章系列不会对所用到的技术进行详细讲解,具体请参考相关文献,阅读文章前最好能对以下技术有一个了解:1.C#语言2.ASP.NET3.设计模式4.关系数据库基础知识5.软件架构基本原则与软件工程基础知识6.基于NBear框架的ORM技术7.JavaScript,Ajax8.ASP.NET AJAX框架(特别是客户端编程)9.HTML,CSS,标准化布局 另外,本文章系列是基于.NET framework2.0框架平台进行讨论,3.5平台的新特性(如LINQ、ASP.NET MVC等)不会讨论,IDE使用Visual Studio 2005,数据库会用到S

4、QLServer2005 Express和Access2003。基于.NET平台的分层架构实战(二)需求分析与数据库设计在实际的项目中,需求分析和数据库的设计是很重要的一个环节,这个环节会直接影响项目的开发过程和质量。实际中,这个环节不但需要系统分析师、软件工程师等计算机方面的专家,还需要相关领域的领域专家参与才能完成。 但是,在这个文章系列中,所要使用的Demo仅仅是一个例子,而且其业务极为简单,因此,这里并不是真正的需求分析和数据库设计,而是将Demo的需求和数据库罗列至此,使朋友们对Demo有一个大体的了解,方便后续文章中开发过程的理解。需求分析:这个项目是一个留言本,其业务极为简单,现

5、将其描述如下。1.任何访问者可以进行留言,留言完成后,不会立即显示正文,而是要经过管理员验证后才可显示。2.任何访问者可以对留言发表评论,未通过验证的留言不可以评论。3.管理员可以对留言进行回复(这个回复不同于评论,是直接显示在正文下面,而且是一个留言只能有一个回复),并可对留言与评论实行删除,以及对留言进行通过验证操作。4.管理员分为超级管理员和普通管理员。超级管理员只有一个,负责对普通管理员实行添加、删除操作。普通管理员可偶多个,负责对留言的管理,并可以修改自己的登录密码。这个项目的用例图如下:数据库设计:设计数据表之前,首先进行实体和关系的识别与确定。通过需求分析,可以观察得出,本项目的

6、实体有:管理员(不包括超级管理员),留言,评论。本项目的关系有:留言与评论间的一对多关系。进一步,数据库各表的设计如下:管理员表(TAdmin)ID int 管理员ID NotNull 主键,自增Name varchar(20) 登录名 NotNullPassword varchar(50) 登录密码 NotNull 使用MD5加密留言表(TMessage)ID int 留言ID NotNull 主键,自增GuestName varchar(20) 留言者用户名 NotNullGuestEmail varchar(100) 留言者E-mail NullContent text 留言内容 Not

7、NullTime datetime 发表留言时间 NotNull Reply text 回复 NullIsPass varchar(10) 是否通过验证 NotNull评论表(TComment)ID int 评论ID NotNull 主键,自增Content text 评论内容 NotNullTime datetime 发表评论时间 NotNullMessageID int 所属留言的ID 外键基于.NET平台的分层架构实战(三)架构概要设计本文主要是对将要实现的架构进行一个总体的描述,使朋友们对这个架构有个宏观上的认识。这篇文章理论性的东西会偏多一点,从下篇开始,将进行实际项目的开发。这篇文

8、章的许多内容摘自我的毕业论文。架构基本原则: 这里,将描述一些在这个架构设计中的基本原则,其中很多都是经典的设计原则,不过针对分层架构的特点,用我自己的语言进行了描述。其中也有我自己提出的原则。逐层调用原则及单向调用原则现在约定将N层架构的各层依次编号为1、2、K、N-1、N,其中层的编号越大,则越处在上层。那么,我们设计的架构应该满足以下两个原则:1.第K(1K=N)层只准依赖第K-1层,而不可依赖其他底层。2.如果P层依赖Q层,则P的编号一定大于Q。其中第一个原则,保证了依赖的逐层性,及整个架构的依赖是逐层向下的,而不能跨层依赖。第二个原则,则保证了依赖的单向性,及只能上层依赖底层,而不能

9、底层反过来依赖上层。针对接口编程,而不是针对实现编程这里所指的接口,不是特指编程语言中的具体语言元素(如C#中由Interface定义的语言接口),而是指一种抽象的,在语义层面上起着接合作用语义体。它的具体实现,可能是接口,可能是抽象类,甚至可能是具体类。我认为,从不同的视角,接口可以有以下两种定义:1.接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是则必须能”的理念。2.接口是在一定粒度视图上同类事物的抽象表示。注意这里我强调了在一定粒度视图上,因为“同类事物”这个概念是相对的,它因为粒度视图不同而不同。具体到N层架构中,针对接口编程的意义在部分上

10、是这样的:现仍约定将N层架构的各层依次编号为1、2、K、N-1、N,其中层的编号越大,则越处在上层,那么第K层不应该依赖具体一个K-1层,而应该依赖一个K-1层的接口,即在第K层中不应该有K-1层中的某个具体类。依赖倒置原则在软件设计原则中,有一种重要的思想叫做依赖倒置。它的核心思想是:不能让高层组件依赖底层组件,而且,不管高层组件和底层组件,两者都应依赖于抽象。那么,这个原则和我们上面的原则是否矛盾呢?其实并不矛盾。因为这个原则定义中的“依赖”是指“具体依赖”,而上面定义中的依赖全部指“抽象依赖”。我对这两种依赖的定义如下:具体依赖如果P层中有一个或一个以上的地方实例化了Q层中某个具体类,则

11、说P层具体依赖于Q层。抽象依赖如果P层没有实例化Q层中的具体类,而是在一个或一个以上的地方实例化了Q层中某个接口,则说P层抽象依赖于Q层,也叫接口依赖于Q层。从这两个定义可以看到,所谓的依赖倒置原则,正是上面提到针对接口编程,而不是针对实现编程,两者在本质上是统一的。综上所述,可以看出,本课题设计的分层架构,应该是这样一种架构:1.N层架构的各层依次编号为1、2、K、N-1、N,其中层的编号越大,则越处在上层。2.架构中仅存在一种依赖,即第K层接口依赖第K-1层,其中1K=N。封装变化原则封装变化的原则定义为:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混杂在一起。开

12、放-关闭原则开发-关闭原则定义为:对扩展开放,对修改关闭。具体到N层架构中,可以描述为:当某一层有了一个新的具体实现时,它应该可以在不修改其他层的情况下,与此新实现无缝连接,顺利交互。单一归属原则在这个架构中,任何一个操作类都应该有单一的职责,属于单独的一层,而不能同时担负两种职责或属于多个层次(实体类及辅助类可以被多个层使用,但它们不属于任何一个层,而是独立存在)。层次划分:目前,典型的分层架构是三层架构,即自底向上依次是数据访问层、业务逻辑层和表示层。这种经典架构经历了时间的考验和实践的多次检验,被认为是合理、有效的分层设计,所以,在本文中,将沿袭这种经典架构,使用数据访问层、业务逻辑层和

13、表示层的三层架构体系。职责划分:目前,在典型的三层架构中,对层次各自的职责划分并没有一个统一的规范,综合现有的成功实践和.NET平台的特殊性,在本文中将三层架构的职责划分如下:数据访问层负责与数据源的交互,即数据的插入、删除、修改以及从数据库中读出数据等操作。对数据的正确性和有效性不负责,对数据的用途不了解,不负担任何业务逻辑。业务逻辑层负责系统领域业务的处理,负责逻辑性数据的生成、处理及转换。对流入的逻辑性数据的正确性及有效性负责,对流出的逻辑性数据及用户性数据不负责,对数据的呈现样式不负责。表示层负责接收用户的输入、将输出呈现给用户以及访问安全性验证。对流入的数据的正确性和有效性负责,对呈

14、现样式负责,对流出的数据正确性不负责,但负责在数据不正确时给出相应的异常信息。模块划分及交互设计:综合以上分析,可在宏观上将整个系统分为一下几个模块:实体类模块一组实体类的集合,负责整个系统中数据的封装及传递。数据访问层接口族一组接口的集合,表示数据访问层的接口。业务逻辑层接口族一组接口的集合,表示业务逻辑层的接口。数据访问层模块一组类的集合,完成数据访问层的具体功能,实现数据访问层接口族。业务逻辑层模块一组类的集合,完成业务逻辑层的具体功能,实现业务逻辑层接口族。表示层模块程序及可视元素的集合,负责完成表示层的具体功能。IoC容器模块负责依赖注入的实现。辅助类模块完成全局辅助性功能。各模块见

15、交互关系如下:这篇中理论比较多,但是它是整个架构的基础,可以帮助朋友们对将要实现的项目架构及要遵循的原则有一个整体的了解。当然,在后续文章中,将主要讨论Demo项目的实际开发过程,那时,这些思想和理论性的东西将得到体现。基于.NET平台的分层架构实战(四)实体类的设计与实现实体类是现实实体在计算机中的表示。它贯穿于整个架构,负担着在各层次及模块间传递数据的职责。一般来说,实体类可以分为“贫血实体类”和“充血实体类”,前者仅仅保存实体的属性,而后者还包含一些实体间的关系与逻辑。我们在这个Demo中用的实体类将是“贫血实体类”。 大多情况下,实体类和数据库中的表(这里指实体表,不包括表示多对多对应

16、的关系表)是一一对应的,但这并不是一个限制,在复杂的数据库设计中,有可能出现一个实体类对应多个表,或者交叉对应的情况。在本文的Demo中,实体类和表是一一对应的,并且实体类中的属性和表中的字段也是对应的。在看实体类的代码前,先看一下系统的工程结构。如上图所示,在初始阶段,整个系统包括6个工程,它们的职责是这样的:Web表示层Entity存放实体类Factory存放和依赖注入及IoC相关的类IBLL存放业务逻辑层接口族IDAL存放数据访问层接口族Utility存放各种工具类及辅助类这只是一个初期架构,主要是将整个系统搭一个框架,在后续开发中,将会有其他工程被陆陆续续添加进来。我们的实体类将放在E

17、ntity工程下,这里包括三个文件:AdminInfo.cs,MessageInfo.cs,CommentInfo.cs,分别是管理员实体类、留言实体类和评论实体类。具体代码如下:AdminInfo.cs:AdminInfo1using System;23namespace NGuestBook.Entity45 /*/ 6 / 实体类-管理员7 / 8 Serializable9 public class AdminInfo10 11 private int id;12 private string name;13 private string password;1415 public in

18、t ID16 17 get return this.id; 18 set this.id = value; 19 2021 public string Name22 23 get return ; 24 set = value; 25 2627 public string Password28 29 get return this.password; 30 set this.password = value; 31 32 3334MessageInfo.cs:MessageInfo1using System;23namespace NGuestBook.E

19、ntity45 /*/ 6 / 实体类-留言7 / 8 Serializable9 public class MessageInfo10 11 private int id;12 private string guestName;13 private string guestEmail;14 private string content;15 private DateTime time;16 private string reply;17 private string isPass;1819 public int ID20 21 get return this.id; 22 set this.

20、id = value; 23 2425 public string GuestName26 27 get return this.guestName; 28 set this.guestName = value; 29 3031 public string GuestEmail32 33 get return this.guestEmail; 34 set this.guestEmail = value; 35 3637 public string Content38 39 get return this.content; 40 set this.content = value; 41 424

21、3 public DateTime Time44 45 get return this.time; 46 set this.time = value; 47 4849 public string Reply50 51 get return this.reply; 52 set this.reply = value; 53 5455 public string IsPass56 57 get return this.isPass; 58 set this.isPass = value; 59 60 6162CommentInfo.cs:CommentInfo1using System;23nam

22、espace NGuestBook.Entity45 /*/ 6 / 实体类-评论7 / 8 Serializable9 public class CommentInfo10 11 private int id;12 private string content;13 private DateTime time;14 private int message;1516 public int ID17 18 get return this.id; 19 set this.id = value; 20 2122 public string Content23 24 get return this.c

23、ontent; 25 set this.content = value; 26 2728 public DateTime Time29 30 get return this.time; 31 set this.time = value; 32 3334 public int Message35 36 get return this.message; 37 set this.message = value; 38 39 4041大家可以看出,实体类的代码很简单,仅仅是负责实体的表示和数据的传递,不包含任何逻辑性内容。下篇将介绍接口的设计。 基于.NET平台的分层架构实战(五)接口的设计与实现接下

24、来,将进行接口的设计。这里包括数据访问层接口和业务逻辑层接口。在分层架构中,接口扮演着非常重要的角色,它不但直接决定了各层中的各个操作类需要实现何种操作,而且它明确了各个层次的职责。接口也是系统实现依赖注入机制不可缺少的部分。本项目的接口设计将按如下顺序进行:1.首先由前文的需求分析,列出主要的UI部分。2.分析各个UI需要什么业务逻辑支持,从而确定业务逻辑层接口。3.分析业务逻辑层接口需要何种数据访问操作,从而确定数据访问层接口。另外,为保证完全的面向对象特性,接口之间的数据传递主要靠实体类或实体类集合,禁止使用DataTable等对象传递数据。由需求分析,列出主要UI需求分析部分,请参看基

25、于.NET平台的分层架构实战(二)需求分析与数据库设计 。有需求分析,可以列出系统中主要应包括以下UI:UI01主页面,列出全部的留言及相应评论,支持分页显示。留言按发表时间逆序显示,评论紧跟在相应留言下。管理员可以通过相应链接对留言执行通过验证、删除、回复以及对评论进行删除操作。游客可通过相应连接进入发表留言评论页面。UI02发表留言页面,供游客发表新留言。UI03发表评论页面,供游客发表评论。UI04回复留言页面,供管理员回复留言。UI05管理员登录页面。UI06管理员修改个人密码的页面。UI07超级管理员登录后的页面,主要提供管理员列表。可以通过相应链接将指定管理员删除。UI08添加新管

26、理员的页面。UI09操作成功完成后的跳转提示页面。UI10系统出现异常时显示友好出错信息的页面。由UI识别业务逻辑操作UI01:按分页取得留言,按指定留言取得全部评论,将指定留言通过验证,将指定留言删除,将指定评论删除UI02:添加新留言UI03:添加新评论UI04:回复留言UI05:管理员登录UI06:修改管理员密码UI07:取得全部管理员信息,删除管理员UI08:添加新管理员经过整理,可得以下接口操作:IAdminBLL:Add(添加管理员),Remove(删除管理员),ChangePassword(修改管理员密码),Login(管理员登录),GetAll(取得全部管理员)IMessage

27、BLL:Add(添加留言),Remove(删除留言),Revert(回复留言),Pass(将留言通过验证),GetByPage(按分页取得留言)ICommentBLL:Add(添加评论),Remove(删除评论),GetByMessage(按留言取得全部评论)这三个接口文件都放在IBLL工程下,具体代码如下:IAdminBLL.cs:IAdminBLL1using System;2using System.Collections.Generic;3using System.Text;4using NGuestBook.Entity;56namespace NGuestBook.IBLL78 /

28、*/ 9 / 业务逻辑层接口-管理员10 / 11 public interface IAdminBLL12 13 /*/ 14 / 添加管理员15 / 16 / 新管理员实体类17 / 是否成功18 bool Add(AdminInfo admin);1920 /*/ 21 / 删除管理员22 / 23 / 欲删除的管理员的ID24 / 是否成功25 bool Remove(int id);2627 /*/ 28 / 修改管理员密码29 / 30 / 欲修改密码的管理员的ID31 / 新密码32 / 是否成功33 bool ChangePassword(int id,string passw

29、ord);3435 /*/ 36 / 管理员登录37 / 38 / 管理员登录名39 / 管理员密码40 / 如果登录成功,则返回相应管理员的实体类,否则返回null41 AdminInfo Login(string name,string password);4243 /*/ 44 / 取得全部管理员信息45 / 46 / 管理员实体类集合47 IList GetAll();48 49IMessageBLL.cs:IMessageBLL1using System;2using System.Collections.Generic;3using System.Text;4using NGues

30、tBook.Entity;56namespace NGuestBook.IBLL78 /*/ 9 / 业务逻辑层接口-留言10 / 11 public interface IMessageBLL12 13 /*/ 14 / 添加留言15 / 16 / 新留言实体类17 / 是否成功18 bool Add(MessageInfo message);1920 /*/ 21 / 删除留言22 / 23 / 欲删除的留言的ID24 / 是否成功25 bool Remove(int id);2627 /*/ 28 / 回复留言29 / 30 / 要回复的留言的ID31 / 回复信息32 / 是否成功33

31、 bool Revert(int id, string reply);3435 /*/ 36 / 将留言通过验证37 / 38 / 通过验证的留言的ID39 / 是否成功40 bool Pass(int id);4142 /*/ 43 / 按分页取得留言信息44 / 45 / 每页显示几条留言46 / 当前页码47 / 留言实体类集合48 IList GetByPage(int pageSize,int pageNumber);49 50ICommentBLL.csICommentBLL1using System;2using System.Collections.Generic;3using

32、 System.Text;4using NGuestBook.Entity;56namespace NGuestBook.IBLL78 /*/ 9 / 业务逻辑层接口-评论10 / 11 public interface ICommentBLL12 13 /*/ 14 / 添加评论15 / 16 / 新评论实体类17 / 是否成功18 bool Add(CommentInfo comment);1920 /*/ 21 / 删除评论22 / 23 / 欲删除的评论的ID24 / 是否成功25 bool Remove(int id);2627 /*/ 28 / 取得指定留言的全部评论29 / 30

33、 / 指定留言的ID31 / 评论实体类集合32 IList GetByMessage(int messageId);33 34由业务逻辑确定数据访问操作IAdminBLL需要的数据访问操作:插入管理员,删除管理员,更新管理员信息,按ID取得管理员信息,按登录名与密码取得管理员,取得全部管理员IMessageBLL需要的数据访问操作:插入留言,删除留言,更新留言信息,按ID取得留言信息,按分页取得留言ICommentBLL需要的数据访问操作:插入评论,删除评论,按留言取得全部评论另外,添加管理员时需要验证是否存在同名管理员,所以需要添加一个“按登录名取得管理员”。对以上操作进行整理,的如下接口

34、操作:IAdminDAL:Insert,Delete,Update,GetByID,GetByNameAndPassword,GetAllIMessageDAL:Insert,Delete,Update,GetByID,GetByPageICommentDAL:Insert,Delete,GetByMessage这三个接口文件放在IDAL工程下,具体代码如下:IAdminDAL.cs:IAdminDAL1using System;2using System.Collections.Generic;3using System.Text;4using NGuestBook.Entity;56nam

35、espace NGuestBook.IDAL78 /*/ 9 / 数据访问层接口-管理员10 / 11 public interface IAdminDAL12 13 /*/ 14 / 插入管理员15 / 16 / 管理员实体类17 / 是否成功18 bool Insert(AdminInfo admin);1920 /*/ 21 / 删除管理员22 / 23 / 欲删除的管理员的ID24 / 是否成功25 bool Delete(int id);2627 /*/ 28 / 更新管理员信息29 / 30 / 管理员实体类31 / 是否成功32 bool Update(AdminInfo adm

36、in);3334 /*/ 35 / 按ID取得管理员信息36 / 37 / 管理员ID38 / 管理员实体类39 AdminInfo GetByID(int id);4041 /*/ 42 / 按管理员名取得管理员信息43 / 44 / 管理员名45 / 管理员实体类46 AdminInfo GetByName(string name);4748 /*/ 49 / 按用户名及密码取得管理员信息50 / 51 / 用户名52 / 密码53 / 管理员实体类,不存在时返回null54 AdminInfo GetByNameAndPassword(string name,string passwor

37、d);5556 /*/ 57 / 取得全部管理员信息58 / 59 / 管理员实体类集合60 IList GetAll();61 62IMessageDAL.cs:IMessageDAL1using System;2using System.Collections.Generic;3using System.Text;4using NGuestBook.Entity;56namespace NGuestBook.IDAL78 /*/ 9 / 数据访问层接口-留言10 / 11 public interface IMessageDAL12 13 /*/ 14 / 插入留言15 / 16 / 留言

38、实体类17 / 是否成功18 bool Insert(MessageInfo message);1920 /*/ 21 / 删除留言22 / 23 / 欲删除的留言的ID24 / 是否成功25 bool Delete(int id);2627 /*/ 28 / 更新留言信息29 / 30 / 留言实体类31 / 是否成功32 bool Update(MessageInfo message);3334 /*/ 35 / 按ID取得留言信息36 / 37 / 留言ID38 / 留言实体类39 MessageInfo GetByID(int id);4041 /*/ 42 / 按分页取得留言信息43

39、 / 44 / 每页显示几条留言45 / 当前页码46 / 留言实体类集合47 IList GetByPage(int pageSize,int pageNumber);48 49ICommentDAL.cs:ICommentDAL1using System;2using System.Collections.Generic;3using System.Text;4using NGuestBook.Entity;56namespace NGuestBook.IDAL78 /*/ 9 / 数据访问层接口-评论10 / 11 public interface ICommentDAL12 13 /*

40、/ 14 / 插入评论15 / 16 / 评论实体类17 / 是否成功18 bool Insert(CommentInfo comment);1920 /*/ 21 / 删除评论22 / 23 / 欲删除的评论的ID24 / 是否成功25 bool Delete(int id);2627 /*/ 28 / 取得指定留言的全部评论29 / 30 / 指定留言的ID31 / 评论实体类集合32 IList GetByMessage(int messageId);33 34基于.NET平台的分层架构实战(六)依赖注入机制及IoC的设计与实现我们设计的分层架构,层与层之间应该是松散耦合的。因为是单向单

41、一调用,所以,这里的“松散耦合”实际是指上层类不能具体依赖于下层类,而应该依赖于下层提供的一个接口。这样,上层类不能直接实例化下层中的类,而只持有接口,至于接口所指变量最终究竟是哪一个类,则由依赖注入机制决定。 之所以这样做,是为了实现层与层之间的“可替换”式设计,例如,现在需要换一种方式实现数据访问层,只要这个实现遵循了前面定义的数据访问层接口,业务逻辑层和表示层不需要做任何改动,只需要改一下配置文件系统即可正常运行。另外,基于这种结构的系统,还可以实现并行开发。即不同开发人员可以专注于自己的层次,只有接口被定义好了,开发出来的东西就可以无缝连接。 在J2EE平台上,主要使用Spring框架

42、实现依赖注入。这里,我们将自己做一个依赖注入容器。 依赖注入的理论基础是Abstract Factory设计模式,这里结合具体实例简单介绍一下。上图以数据访问层为例,展示了Abstract Factory模式的应用。如图,现假设有针对Access和SQLServer两种数据库的数据访问层,它们都实现了数据访问层接口。每个数据访问层有自己的工厂,所有工厂都实现自IDALFactory接口。而客户类(这里就是业务逻辑层类)仅与工厂接口、数据访问层接口耦合,而与具体类无关,这样,只要通过配置文件确定实例化哪个工厂,就可以得到不同的数据访问层。然而,这种设计虽然可行,但是代码比较冗余,因为这样需要为数据访问层的每一个实现编写一个工厂,业务逻辑层也一样。在以前,我们毫无办法,但是,.NET平台引入的反射机制,给我们提供了一种解

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论