近期在学习三层和设计模式,也看了许多的博客,所谓贪多嚼不烂,不学狗熊掰棒子,适时地总结一下心得。
三层架构
所谓三层架构具体指的是:
1. UI层(简称U层,即用户界面层)
2. BLL层(简称B层,即业务处理层)
3. DAL层(简称D层,数据访问层)
为什么要有三层这种概念呢,这么分层有什么作用呢?
我想大家都知道,这么做的目的是为了使程序更加的健壮,减少耦合,提高复用程度等等。没错,这就是最大的目的。
在我们之前的VB机房项目中,我们把U层和B层的内容糅杂在一起,这样就导致程序很脆弱:一旦用户要修改需求,功能需要改变,那么我们写的程序很有可能需要重新推倒重来,这样的程序不是我们想要的。
那么三层是如何帮助我们解决问题的呢?我们先看看三层该干些什么工作。
UI层: 关注的是用户界面。它不涉及业务功能该如何实现,最多的就是为业务功能提供一个事件用来触发行为而已(比如点击一个按钮)。
UI层的代码做什么?
- 优化界面,为各个控件的功能实现提供代码支持。(比如说,界面全屏以后,Picture控件要随之变大等等)
- 声明字段,为B层提供参数,调用B层,跳转界面或者其他。(比如说登录,用字段接受文本框的值,将字段传给B层,某类或某类的函数参数)
- 如果有需要通过实体层传参的情况,那么可以和实体层打交道,将值传到实体层。其作用与上一条一致。
- 对某些控件进行简单的逻辑处理。(请见文章末尾)
private void btn_Login_Click(object sender, EventArgs e) //演示第2点。
{
string userid = txt_UserID.Text;
string password = txt_Password.Text;
BLL.dataProcess data = new BLL.dataProcess();
if (data.DTprcs(userid, password)) //B层返回值为Bool类型
{
MessageBox.Show("登录成功"); //可以跳转界面
}
else
{
MessageBox.Show("登录失败");
}
}
BLL层:通过U层传进来的参数进行相关的业务处理。
什么叫业务处理呢?
比如说是登录功能(我们想要的结果是当用户名和密码与注册时的数据一致时,才能是登录成功)。
登录功能的业务处理所做的工作大概是以下内容:
- 接受UI层的数据 [通过参数接受] (即用户在文本框输入的值)。
- 调用D层,接受D层返回的数据 [定义一个与D层返回值类型相同的变量,接收D层的返回值]
- 对比UI层的数据与D层的数据是否相同,相同可以返回一个Bool型的值,true。
最终的目的就是查询数据库中的数据是否有用户在UI层输入的数据,这就是登录的业务逻辑。
public bool DTprcs(string userid, string password) //参数为U层传进来的值
{
DAL.user_Login Daluserinfo = new DAL.user_Login(); //实例D层对象
List<string> userinfo = new List<string>(2); //因为返回值只能有一个,这里没用到实体层,所以采用List(集合)来接受从数据库返回的数据。
userinfo = Daluserinfo.checkUser(userid, password); //接受D层返回来的数组。
if (userinfo.Contains(userid) && userinfo.Contains(password)) //如果数据库返回来的值包含U层传进的值。
{
return true; //将true返回到U层
}
else
{
return false; //将false返回到U层
}
}
DAL层:目前我理解的D层就是接收B层的参数,根据B层的需求进行对数据库的操作。
public List<string> checkUser(string userid,string password)
{
//下列语句有SQL注入的风险,强烈不建议这么写。
string txtsql = @"select * from [User] where UserID='" + userid + "' and Password='" + password + "'";
AccessConfig InitialDbConn = new AccessConfig();
SqlCommand sqlCmd = InitialDbConn.Access(txtsql);
SqlDataReader reader = sqlCmd.ExecuteReader();
//前面是为了连接数据库,从这里看代码即可
while (!reader.Read()) //若数据库中无UI层输入的数据
{
userid = ""; //将空值赋值给字段Userid和password
password = "";
break;
}
while (reader.Read()) //若存在
{
userid = reader.GetString(0); //将查到的数值赋值给字段Userid和password
password = reader.GetString(1);
}
List<string> userinfo = new List<string>(2); //利用数组接受字段
userinfo.Add (userid.Trim());
userinfo.Add (password.Trim());
return userinfo; 返回数组
}
1.对某些控件进行简单的逻辑处理。
解释:在UI层进行文本框的判定是否为空的代码,具体放在哪个层,是值得商榷的。
放在U层吧,感觉不合适,因为U层不改涉及判断;放在B层吧,那更不对了,先不说循环依赖,单就功能而言也不是业务逻辑的内容。
之后我们还会介绍Facade层(用来隔离客户端与系统的模式,外观模式),放在Facade层也很怪异。就所观察而言,大多数的登录都放在了UI层,比如说QQ的登录,如果文本框为空,会给出提示,不为空才进行登录,无论你输入什么内容,所以大家关于这个问题,放在U层就妥妥的了。