今天带大家学习一下七层,上一篇博客中我介绍了三层架构,不知大家还否记得,三层架构分别为UI(界面层)、BLL(业务逻辑层)、DAL(数据访问层)。层层递进,每层之间存在一定的弱耦合的联系,三层架构的思想无非就是解耦,让系统的扩展性以及维护性更加方面,符合面向对象的思想。那为什么又出现了七层呢,当然是为了更好的解耦了,三层之间虽然做到了一定的解耦,但是并没有完全实现解耦,他们之间存在级联修改,当U层发生变化,相应的B层D层也会发生修改。每个人对七层有着不一样的理解,具体哪七层也有着不同的解释,今天介绍一下我的七层架构吧。
三层架构到七层架构:增加了外观模式、抽象工厂层、SqlHelper层、IDAL接口层
三层架构:UI→BLL→DAL
七层架构:
现在就让我结合机房重构登陆界面,详细的介绍一下七层登录吧。
关于七层架构,有的小伙伴就要问题了,我先写哪一层的代码呢?如果你不是很明确的话,七层之间各层之间的引用关系,你还没有详细的弄清楚。下面就让我详细的介绍一下七层登录。
Entity 层、DAL层、 IDAL层、Factory层、facade层、BLL 层、UI层
一.实体层 Entity
实体层说白了就是一个公共信息的访问站,它与数据库中的数据表数据相对应,用来存放用户输入的信息。
二、IDAL层:定义D层统一的接口方法,实现D层各个功能。说白了就是一个接口,具体的功能靠D层实现。
具体代码如下:
using Entity;
namespace IDAL
{
public partial interface UserIDal
{
UserInfo GetByID(int id);
}
}
三、DAL层:实现IDAL层中的方法,访问数据库中的数据,对数据进行一定的操作(增删改查)。
两点需要注意:
1.我们根据用户输入的账号,判断用户是否存在,如果存在返回用户的所有信息,目的是检查用户的密码是否输入错误,二是根据用户返回的用户级别,提供给用户不同功能界面。
2.DAL层:sqlHelper 的封装在DAL层,目的连接数据库,实现对数据库的增删改查的操作,所以,SqlHelper不可以当做一层来看待,存在的目的服务于DAL层
具体代码如下:
using System;
using System.Data;
using Entity;
using System.Data.SqlClient;
namespace DAL
{
public class frmLoginDAL:IDAL.UserIDal //实现接口的方法
{
UserInfo user = null;//声明一个用户,
public UserInfo GetByID(int id)// 根据用户输入的信息判断是否存在该用户
{
string sql = @"SELECT * FROM [User_Info] WHERE UserID=@UserID"; //构造语句,匹配数据表
SqlParameter p = new SqlParameter("@UserID", id);//为语句构造参数
DataTable dt = sqlHelper.GetDataTable(sql, p);//执行查询得到结果
if (dt.Rows.Count>0)
{
user = new UserInfo()//用户存在
{
UserID = Convert.ToInt32(dt.Rows[0][1]),
PassWord = dt.Rows[0][2].ToString(),
Level=dt.Rows[0][3].ToString(),
UserName=dt.Rows[0][4].ToString(),
};
}
return user;//返回一个用户对象
}
}
}
D层的返回来的信息如何传回到B层呢?
四、Factory(工厂层):定义一个接口层,实现BLL层与DAL层之间的数据传递。工厂层用到了抽象工厂+反射+配置文件,实现了不同数据库之间的连接。反射+配置文件的最大作用在更方便的更改不同数据库的连接。
工厂+反射+配置文件
反射:最大的有点就是用字符串代表数据库,更改字符,就可以更换数据库。
具体代码如下:
using System.Reflection;
using System.Configuration;
namespace Factory
{
public class LoginFactory
{
private static readonly string AssemblyName = ConfigurationManager.AppSettings["Dal"];
//前提D层中“DAL.sqlserver”表名命名的,才方便更换数据库
public IDAL.UserIDal CreateUser()
{
string ClassName = AssemblyName + "." + "frmLoginDAL";//DAL层的类名
return (IDAL.UserIDal)Assembly.Load(AssemblyName).CreateInstance(ClassName); //反射加工厂的应用
}
}
}
五、BLL层:执行特定的业务逻辑。
登陆界面BLL层:1.对D层返回来的信息进行判断,用户是否存在的问题,2.如果存在还会产生,返回更加具体的信息给U层
using IDAL;
using Factory;
using Entity;
namespace BLL
{
public partial class UserBll
{
public LoginState Login(int id, string pwd, out string level)
{
level = null;//定义Level为空值
//根据用户名进行对象查询
LoginFactory fact = new LoginFactory();//实例化登陆工厂对象
UserIDal idal = fact.CreateUser();//调用工厂方法创建接口
UserInfo user = idal.GetByID(id);//接受D层的返回值
if (user == null)
{//用户名错误
return LoginState.IdError;
}
else
{//用户名正确,要么密码错误,要么没有错
if (pwd.Equals(user.PassWord))
{//密码正确登陆成功
level =user.Level ;//返回用户等级
return LoginState.Ok;
}
else
{
return LoginState.PwdError;//密码错误
}
}
}
}
}
六、Facade层,提供一个门面,一个UI层可以会访问多个BLL层,提供一个外观层,好比提供了一个简单的入口,UI层和BLL层之间的耦合度。返回B层的信息给UI层
using BLL;
using Entity;
namespace Facade
{
public partial class frmLoginFacade
{
UserBll uBLL = new UserBll();//实例化B层对象
public LoginState Login(int id, string pwd, out string level)
{
level = null;//定义不同身份为空
return uBLL.Login(id, pwd, out level);//返回B层的值
}
}
}
七、UI层:1、提供一个登陆界面,获取用户输入的信息 2、给用户提供特定的业务功能,或者数据
具体代码如下:
using System.Windows.Forms;
using Entity;
using Facade;
namespace U
{
public partial class frmLoginUI : Form
{
public frmLoginUI()
{
InitializeComponent();
}
private void btOk_Click(object sender, EventArgs e)
{
if (txtCardNo.Text.Trim() == "" || txtPassword.Text.Trim() == "")//判断用户是否输入帐号或者密码
{
MessageBox.Show("请将登陆信息填写完整");
return;//目的是停止后面代码的执行,返回if语句
}
//获取用户输入的信息
string level;//定义用户等级
int ID = Convert.ToInt32(txtCardNo.Text.Trim());//接收用户输入的信息
string pwd = txtPassword.Text.Trim();
frmLoginFacade facade = new frmLoginFacade(); //实例化外观层,接收B层返回来的信息
LoginState State = facade.Login(ID, pwd, out level);
UserInfo user = new UserInfo();// 实例化登陆对象
switch (State)
{
case LoginState.Ok:
frmMain main = new frmMain();
main.Tag = level;//判断用户级别:操作员/管理员
user.UserID = ID;//将返回来的账号赋值给实例化的对象
main.Show();//显示主窗体页面
this.Hide();//隐藏登陆窗体
break;
case LoginState.IdError:
MessageBox.Show("用户名错误");
break;
case LoginState.PwdError:
MessageBox.Show("密码错误");
break;
default:
break;
}
}
private void btExit_Click(object sender, EventArgs e)
{
this.Close();//关闭窗体
}
}
}
配置文件:按照我们以前的VB机房为例,数据库的连接是在模块中进行连接的,当系统完成以后,是不可以修改里面内容的,配置文件的存在,就是如果必须修改,对配置文件进行修改,方便程序的开发和维护。
具体代码如下:
机房重构中的七层,实现了三层架构之间级联式的解耦,方面用户的维护与修改。本篇博客中还存在很多的知识点,例如配置文件、反射、SqlHelper 方法的使用,DataTable等知识点的总结,最近我将持续分别介绍给大家。