购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.2 解耦第一步——接口要上位

从本节开始,我们要开始慢慢地搭建自己的代码结构了,我们将要做一个类似“川商卡”的项目。MOL是山西人,所以把项目名称定为“晋商卡”。

3.2.1 代码结构的前提

1. 创建数据库

首先,我们必须有一个数据库来供程序使用,MOL在前面的章节中已经提到PD(PowerDesigner)是设计数据库的利器,所以在这里还是使用PD来设计“晋商卡”的数据结构。为了方便大家,MOL已经把设计好的概念模型(CDM)和物理模型(PDM)都打包放在本书的配套资源里了(代码位置:源代码\第3章\数据库模型)。打开Workspace.sws,依次展开JinCardPD→JinCardPDM选项,选择菜单栏中的Database→Generate Database命令,如图3-1所示。

图3-1 生成数据库

在弹出的对话框中填写输入脚本存放的路径后,单击“确定”按钮,如图3-2所示。

图3-2 填写输入脚本存放的路径

这样,创建数据库的脚本就生成了,是不是特别简单?把这个脚本放到SQL Server中执行一下,就可以得到我们需要的数据库表了(必须先在SQL Server中创建数据库JinCardDB),如图3-3所示。

图3-3 生成后的数据库

每个表的含意和表中字段的范围都在PD文件中进行了描述,MOL就不再赘述了。在下面的讲述中,我们只针对两张表进行搭建架构,其他的表怎么办呢?这个问题放到本章的3.3节中进行讲述。

下面用到的两张表分别是T_CustomInfo_TB用户信息表、T_Order_TB订单表。之所以选择这两张表进行讲述,是因为用户表和订单表存在“一对多”的关系,这样可以理解在面向对象的世界里,一对多是什么样子的。

2. 创建基础的三层架构

除了数据表之外,还需要搭建一个简单的三层架构,这个三层架构实现对数据库表进行CRUD(增、删、改、查)。关于三层架构,前面已经提到过了,即包含了DAL(数据访问层)、BLL(业务逻辑层)和UI(用户界面层)这三层。后来,我们在这个基本三层架构中增加了实体层(Model Layer)。

我们就按照这样的思路去建立一个简单的三层架构,这个架构中使用SqlHelper实现对数据库的访问,使用MVC实现用户界面的CRUD。具体搭建步骤请参考第2章,搭建完成后的代码架构如图3-4所示(代码位置:源代码\第3章\简单三层)。

图3-4 简单三层代码示意图

这个代码框架比较简单,大家花点时间就可以自己写出来。需要注意的是,MOL在给出的代码中所使用的是微软提供的SqlHelper,在这个基础上,MOL添加了将DataTable转换为实体的方法。

3.2.2 创建接口层

我们更希望在使用实体的时候,不要直接去实例化一个对象,例如:

dalClass dal=new dalClass();           //实例化一个dal 对象

大家可以设想一下,一个公司可能有很多程序员,有的程序员只会写与数据库打交道的代码(DAL层),有的程序员只会写业务逻辑代码(BLL层),有的程序员只会写UI代码。如果在BLL层直接实例化一个DAL对象,可以想象一下这是什么样的场景。

BLL程序员:我想要一个获取用户信息的方法,你写完以后把函数名发给我。

DAL程序员:写完了,public ArrayList getUser()。

BLL程序员:嗯?返回的是什么?ArrayList里放的是什么?

DAL程序员:集合里面当然放的是用户对象集合了啊。

BLL程序员:但是ArrayList里的元素是不固定的,万一哪天我取出一个元素不是“用户”类型,那程序岂不是要报错了?

DAL程序员:那你不会用try…catch来处理一下?

BLL程序员:try…catch不是这样用的啊……

程序员的交流往往就是这么简单直接,而且毫无美感。没办法,谁让程序员就是一种高智商低情商的“物种”呢。

吵完了以后,DAL程序员做出了让步,修改函数为:

public List<User> getUser()

BLL程序员得知消息以后,欣慰地写下了:

DAL dalInstance=new DAL();
List<User> userList=dalInstance.getUser();

好景不长,DAL程序员找到了BLL程序员。

DAL程序员:我们老大说了,这个函数名不符合编码规范,返回类型也没有遵循最小原则,所以这个函数需要修改,现在改为:

public IList<User> getLiveUser()

BLL程序员:你是猴子派来的救兵吗?你这一改,我也要跟着改……

BLL程序员很无奈,只能修改程序为:

DAL dalInstance=new DAL();
IList<User> userList=dalInstance.getLiveUser();

改完以后,默默地祈祷DAL不要再修改了。

直到DAL程序员再告诉BLL程序员说要修改的时候,两人之间就上演了不死不休的争吵。

其实,并不是这两个人有什么私人恩怨,也不能追究谁对谁错,如果要说有一个人错的话,那也只能是架构师,一个坏的架构足以搞垮一个优秀的团队。

上面描述的这种情景中,BLL程序员对DAL程序员有着较强的依赖,DAL层的修改经常会影响到BLL层。我们通常把这种较强依赖的关系叫做“强耦合”。

还记得前面说的一句名言吗——计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。

我们增加一个接口层来解决上面提到的强耦合问题。这个接口层承上启下,一手连接DAL,一手连接BLL。其实它更重要的作用是隔开了BLL和DAL层,使它们不会发生直接关系。增加了接口层以后,解决方案如图3-5所示。

图3-5 增加了IDAL接口层

图3-5只是拉了一个接口层IDAL,如何让IDAL一手托两家,连接DAL和BLL层呢?

1. 连接DAL层

IDAL连接DAL层的意义在于,IDAL给DAL层做出了规范。比如在IDAL中定义了一个接口:

void InsertUser(T_CustomInfo_TB user);

那么,在DAL中就一定要实现这个接口。

Public void Insertuser(T_CustomInfo_TB user)
{
          //实现代码
}
2. 连接BLL层

IDAL连接BLL层的意义在于,IDAL只告诉BLL层说我可以干什么,但我是怎么干这些事的,就不告诉你了。这样,BLL层就只关心IDAL的作用。就好像我要做一个雪糕,那么就需要找一个可以冷冻的家电(如冰箱、冷柜……),但我不需要关心这个家电是如何工作的,只需要知道这个家电有冷冻功能即可。“有冷冻功能的家电”就是IDAL,“制作雪糕”就是BLL,而具体的冰箱或冷柜就是DAL。

在BLL中调用IDAL的过程是这样的: HFtoYmwSsY+Za5j9W0shSGamx2DOPBjM1LhHtKmlg7eKo1F5PrPDuE+BKnxUtUnp

//实例化一个IDAL 接口
IDAL customerDAL=new CustomerDAL();
//调用接口的InsertUser()方法
customerDAL.InsertUser(user);
点击中间区域
呼出菜单
上一章
目录
下一章
×