好不容易完成了机房重构的七层登陆架构,笔者感觉到非常心碎啊。七层登陆是三层登陆的加强版,可以说没有三层登陆就没有七层登陆。
七层登陆共分为UI(用户界面层),FACADE(外观层),FACTORY(工厂层),IDAL(接口),DAL(数据处理层),BLL(业务逻辑层),ENTITY(实体层)。
配置文件:配置文件是标准的XML文件,XML标记和属性区别大小写。随安装程序一起被安装到计算机上的文件,里面存放安装号的应用程序运行时需要的参数,他可以按需求更改参数,开发人员可以使用配置文件来更改设置,而不必重编译应用程序。配置文件能在数据库连接字符和数据库更换上,给我们省去大量的工作。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!--预定义配置节,注意大小写;它是整个程序的配置。如果是对当前用户的配置,则使用userSettings配置节,格式要求与appSettings书写要求一样-->
<add key="ConnStr" value="server=DESKTOP-C0UO8R2; database=login; User ID=sa; Password=123"/>
<!--这里的server、User ID、Password和database不区分大小写,数据库名称YZY.Charge-->
<add key="DB" value="DAL"/>
</appSettings>
</configuration>
层与层之间的关系如下图
UI(用户界面层):收集用户输入的数据然后传给外观层,还有是把从外观层接受到的数据显示给用户看,这一层是主要和用户进行交互的。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using LoginUI;
namespace UI
{
public partial class frmLogin : Form
{
public frmLogin()
{
InitializeComponent();
}
private void btnOK_Click(object sender, EventArgs e)
{
//登录前,先判断是否为空
if (txtUserID.Text.Trim() == "")
{
MessageBox.Show("未输入用户名,请先输入!", "提示", MessageBoxButtons.OK);
txtUserID.SelectAll();
txtUserID.Focus();
}
if (txtPassword.Text == "")
{
MessageBox.Show("未输入密码,请先输入!", "提示");
txtPassword.SelectAll();
txtPassword.Focus();
}
//修改密码--窗体传值
Pass.txtPassword = txtPassword.Text;
Pass.txtUserID = txtUserID.Text;
try
{
Facade.LoginFacade Facade = new Facade.LoginFacade();//实例化一个外观
Entity.User_Info user = new Entity.User_Info();//实例化一个用户
user.UserID = txtUserID.Text.Trim();//接收控件传来的用户名信息,将字符串转换成int类型
user.PassWord = txtPassword.Text;//接收控件传来的密码信息
Boolean flag = false;//定义要给bool型变量
Facade.LoginFacade Flogin = new Facade.LoginFacade();//实例化外观
flag = Flogin.SelectUser(user);//使用外观方法,返回给User
if (flag != false)
{
MessageBox.Show("登录成功!", "提示");
this.Hide();//隐藏当前窗体
this.DialogResult = DialogResult.OK;//实现界面跳转
frmMain main = new frmMain();//实例化一个窗体
main.Show();//显示实例化的窗体
}
else
{
MessageBox.Show("用户名或者密码错误", "提示");
txtUserID.SelectAll();
txtUserID.Focus();
}
}
catch (Exception)
{
MessageBox.Show("出现错误", "提示");
txtPassword.Clear();
txtUserID.Clear();
txtUserID.SelectAll();
txtUserID.Focus();
}
}
FACADE(外观层)
用户提出请求后,外观曾对用户数据按照业务逻辑层要求的接口参数封装规则封装用户数据,然后调用业务接口层对外提供相应的命令接口。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entity;
using BLL;
namespace Facade
{
public class LoginFacade
{
public Boolean SelectUser(User_Info user)
{
bool flag;
LoginBLL userBLL = new LoginBLL();//实例化LoginBLL
flag = userBLL.UserBLL(user);//进入BLL层,并执行操作,返回有用户为true,返回无用户为false
return flag;
}
}
}
IDAL:定义一个同意的接口,解除B层和D层的耦合
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace IDAL
{
public interface LoginIDAL
{
DataTable SelectUser(Entity.User_Info User_Info);//DataTable表示内存中的数据的一个类,实现了增删改查中的查---查找用户
}
}
DAL层:对于数据和命令的不同,处理方式也不同,我们将不同的处理方式归类,并将接口层传入的数据及命令流入对应的处理流程。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace BLL
{
public class LoginBLL
{
public bool UserBLL(Entity.User_Info User_Info)
{
Factory.LoginFactory factory = new Factory.LoginFactory();//实例化工厂
IDAL.LoginIDAL idal = factory.CreateUser();//进入工厂层,使用工厂方法创建接口
DataTable table = idal.SelectUser(User_Info);//接收D层的返回值
bool flag;
if (table.Rows.Count==0)//返回的DataTable类型,如果它的行数等于0,说明没有符合该账号密码的用户
{
flag = false;
}
else
{
flag = true;
}
return flag;
}
}
}
实体层:不同的处理流程分析数据和命令产生出对应的一个实体,这个实体根据其本身的属性和方法一斤上层传入的命令,将数据处理为数据访问需要的接口参数,并将数据访问层提交访问数据库的请求,并向业务接口层返回范文结果。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entity
{
public class Student_Info
{
//定义学号字段
private string studentNo;
public string StudentNo
{
get { return studentNo; }
set { studentNo = value; }
}
//定义学生姓名字段
private string studentName;
public string StudentName
{
get { return studentName; }
set { studentName = value; }
}
数据访问层:将数据转化为数据库可以识别的SQL语句,并访问数据库层,访问结果会返回给实体层。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using IDAL;
namespace DAL
{
public class LoginDAL:LoginIDAL
{
public DataTable SelectUser(Entity.User_Info User_Info)//查找用户
{
SQLHelper sqlHelper = new SQLHelper();//实例化一个SQLHelper
SqlParameter[] sqlParams = { new SqlParameter(@"UserID", User_Info.UserID),
new SqlParameter("@Password", User_Info.PassWord) };
string sql = @"SELECT * FROM [User_Info] WHERE UserID=@UserID and PassWord=@Password";//查询语句
DataTable table = sqlHelper.ExecuteQuery(sql, sqlParams, CommandType.Text);
return table;
}
}
}
FACTORY层(工厂层)工厂通过读取配置文件,实现了解耦。在以后更换数据库的时候,只需要修改配置文件,增加一个新的类,而不需要修改原来的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Configuration;
namespace Factory
{
public class LoginFactory
{
string StrDB=ConfigurationManager.AppSettings["DB"];//接收来自配置文件的数据
public IDAL.LoginIDAL CreateUser()
{
string ClassName = StrDB + "." + "LoginDAL";//DAL层的类名
return (IDAL.LoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);//反射+工厂的应用
}
}
}