架构设计基本原则
系统的工程结构
在初始阶段,整个系统包括6个工程,它们的职责是这 样的: Web——表示层 Entity——存放实体类 Factory——存放和依赖注入及IoC相关的类 IBLL——存放业务逻辑层接口族 IDAL——存放数据访问层接口族 Utility——存放各种工具类及辅助类 这只是一个初期架构,主要是将整个系统搭一个 框架,在后续开发中,将会有其他工程被陆陆续续添 加进来。 实体类将放在Entity工程下
其中第一个原则,保证了依赖的逐层性,及整个架构 的依赖是逐层向下的,而不能跨层依赖。第二个原则 ,则保证了依赖的单向性,及只能上层依赖底层,而 不能底层反过来依赖上层。
针对接口编程,而不是针对实现编程
这里所指的接口,不是特指编程语言中的具体语言元素(如C#中 由Interface定义的语言接口),而是指一种抽象的,在语义层 面上起着接合作用语义体。它的具体实现,可能是接口,可能是 抽象类,甚至可能是具体类。 从不同的视角,接口可以有以下两种定义: 1.接口是一组规则的集合,它规定了实现本接口的类或接口 必须拥有的一组规则。体现了自然界“如果你是……则必须能 ……”的理念。 2.接口是在一定粒度视图上同类事物的抽象表示。注意这里 我强调了在一定粒度视图上,因为“同类事物”这个概念是相对 的,它因为粒度视图不同而不同。 具体到N层架构中,针对接口编程的意义在部分上是这样的: 现仍约定将N层架构的各层依次编号为1、2、…、K、…、N1、N,其中层的编号越大,则越处在上层,那么第K层不应该依 赖具体一个K-1层,而应该依赖一个K-1层的接口,即在第K层中 不应该有K-1层中的某个具体类。
第一步,我们要将Access数据库搭建完成 ,具体做法如下。 在Web工程下新建一个文件夹,命名 为AccessData,并在其中新建一个mdb文 件(即Access数据库文件),按照需求 分析的数据库设计构架,将数据表及表 间关系建好,
第二步,我们要进行一些配置。 打开Web工程下的Web.config文件,在其中的 appSettings节点下,添加如下键值: <add key="AccessConnectionString" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source={DBPath}"/> <add key="AccessPath" value="~/AccessData/AccessDatabase.mdb"/> 第一条为Access的连接字符串,第二条为 Access数据库文件的路径,其中“~”表示网站根目 录
第三步,新建一个工程。 我们要新建一个工程AccessDAL,用 来存放Access数据访问层的代码。 准备工作做完了,现在来实现具体 的代码。
1.编写数据访问助手类 因为很多数据访问操作流程很相似,所以,这 里将一些可复用的代码抽取出来,编写成助手类, 以此减少代码量,提高代码复用性。 这个助手类放在AccessDAL下,叫 AccessDALHelper,主要负责Access数据库的访问 。它包括三个方法: GetConnectionString:从配置文件中读取配 置项,组合成连接字符串。 ExecuteSQLNonQuery:执行指定SQL语句,不 返回任何值,一般用于Insert,Delete,Update命 令。 ExecuteSQLDataReader:执行SQL语句返回查 询结果,一般用于Select命令。
职责划分
数据访问层——负责与数据源的交互,即数据的插入 、删除、修改以及从数据库中读出数据等操作。对数 据的正确性和有效性不负责,对数据的用途不了解, 不负担任何业务逻辑。 业务逻辑层——负责系统领域业务的处理,负责逻辑 性数据的生成、处理及转换。对流入的逻辑性数据的 正确性及有效性负责,对流出的逻辑性数据及用户性 数据不负责,对数据的呈现样式不负责。 表示层——负责接收用户的输入、将输出呈现给用户 以及访问安全性验证。对流入的数据的正确性和有效 性负责,对呈现样式负责,对流出的数据正确性不负 责,但负责在数据不正确时给出相应的异常信息。
模块划分及交互设计
实体类模块:一组实体类的集合,负责整个系统中数据的封装及传递。
数据访问层接口族:一组接口的集合,表示数据访问层的接口。
业务逻辑层接口族:一组接口的集合,表示业务逻辑层的接口。 数据访问层模块:一组类的集合,完成数据访问层的具体功能,实现数 据访问层接口族。 业务逻辑层模块:一组类的集合,完成业务逻辑层的具体功能,实现业 务逻辑层接口族。
2.实现具体的数据访问操作类 因为前面已经定义了数据访问层接口 ,所以实现数据访问操作类就是很机械 的工作了。 这里主要包括三种类型的操作,一种 是修改型,如Insert;一种是返回单个 实体类型,如GetByID;还有一种是返回 实体类集合型,如GetAll。
依赖注入机制及IoC的设计与实现
业务逻辑层的实现
在实际应用中,业务逻辑层是至关重要 的,他承载着整个系统最核心的部分, 也是客户最关注的部分。这一部分的实 现,通常需要技术专家和领域专家通力 合作。
业务逻辑层主要承担了以下职责: 1.对不同数据访问层的封装。使得表示层可以不关心具 体的数据访问层。 2.业务逻辑数据的填充与转换。如管理员口令的加密。 3.核心业务的实现。这里很多业务逻辑只有一行代码, 即一个业务逻辑方法恰好对应一个数据访问方法,但是也有 通过多个数据访问方法实现业务的。如AdminBLL中的 ChangePassword方法就调用了AdminDAL的GetByID和Update 两个方法。另外,虽然许多方法只调用一个数据访问方法, 但是从命名看也能看出两者着眼点的不同。如AdminDAL中的 GetByNameAndPassword,这个名字显然是从数据库的角度看 问题——指按照指定的Name和Password两个字段的值取出相 应信息,至于这样做的业务意义它不需要知道。而AdminBLL 中,调用它的方法叫Login,这是从业务角度看问题——即 这个方法是管理员登录
分层架构概要设计
架构设计基本原则
这里,将描述一些在这个架构设计中的 基本原则,其中很多都是经典的设计原 则
逐层调用原则及单向调用原则
现在约定将N层架构的各层依次编号为1、2、…、K、 …、N-1、N,其中层的编号越大,则越处在上层。那 么,我们设计的架构应该满足以下两个原则:
第K(1<K<=N)层只准依赖第K-1层,而不可依赖其他底层。 如果P层依赖Q层,则P的编号一定大于Q。
数据访问层的一种实现:Access+SQL
通过前面的工作,整个系统的框架算是基本搭 建完了,下面,我们要具体实现各个层次。关 于数据访问层的实现,我们讨论三种实现方式 ,第一种:Access+动态生成SQL。 顾名思义,这种实现将使用Access作为后台数 据库,而操作方式也是最基本的使用SQL命令。 在具体编写实现代码之前,我们需要做一些准 备工作:
这里设计的分层架构,层与层之间应该 是松散耦合的。因为是单向单一调用, 所以,这里的“松散耦合”实际是指上 层类不能具体依赖于下层类,而应该依 赖于下层提供的一个接口。这样,上层 类不能直接实例化下层中的类,而只持 有接口,至于接口所指变量最终究竟是 哪一个类,则由依赖注入机制决定。
配置 首先,需要在Web工程的Web.config 文件的<appSettings>节点下添加如下两 个项: <add key="DAL" value=""/> <add key="BLL" value=""/> 这两个配置选项分别存储要应用的 数据访问和也业务逻辑层的程序集名称 。value目前是空,是因为目前还没有各 个层次的具体实现。
依赖倒置原则
从这两个定义可以看到,所谓的依赖倒置原则 ,正是上面提到针对接口编程,而不是针对实 现编程,两者在本质上是统一的。 综上所述,可以看出,本课题设计的分层 架构,应该是这样一种架构: 1.N层架构的各层依次编号为1、2、…、K 、…、N-1、N,其中层的编号越大,则越处在 上层。 2.架构中仅存在一种依赖,即第K层接口 依赖第K-1层,其中1<K<=N。
实现缓存操作辅助类 为实现缓存操作,我们将缓存操作 封装成一个辅助类,放在Utility工程下
封装依赖注入代码 因为很多依赖注入代码非常相似, 为了减少重复性代码,我们将可复用的 代码先封装在一个类中。 (这个类放在 Factor现数据访 问层工厂和业务逻辑层工厂。
单一归属原则
在这个架构中,任何一个操作类都应该 有单一的职责,属于单独的一层,而不 能同时担负两种职责或属于多个层次( 实体类及辅助类可以被多个层使用,但 它们不属于任何一个层,而是独立存在 )。
层次划分
目前,典型的分层架构是三层架构,即 自底向上依次是数据访问层、业务逻辑 层和表示层。 这种经典架构经历了时间的考验和 实践的多次检验,被认为是合理、有效 的分层设计,所以,在本文中,将沿袭 这种经典架构,使用数据访问层、业务 逻辑层和表示层的三层架构体系。
1.建立工程 在这个架构中,业务逻辑层是可以 替换的。及业务逻辑层不是直接耦合于 表示层,而是通过依赖注入机制实现。 所以,我们这里将这个业务逻辑层不直 接命名为BLL,而是新建一个叫 SimpleBLL的工程,放置我们这个业务逻 辑层的相关代码。
封装变化原则
封装变化的原则定义为:找出应用中可 能需要变化之处,把它们独立出来,不 要和那些不需要变化的代码混杂在一起 。
开放-关闭原则
开发-关闭原则定义为:对扩展开放,对 修改关闭。 具体到N层架构中,可以描述为:当 某一层有了一个新的具体实现时,它应 该可以在不修改其他层的情况下,与此 新实现无缝连接,顺利交互。