Com base nas três camadas, sete camadas foram estendidas para reduzir ainda mais o acoplamento (grau de proximidade) entre a camada de IU, a camada BLL e o DAL. Vamos dar uma olhada no breve diagrama de pacote primeiro e ver como eles são. relação:
Pode-se ver neste diagrama de pacote que a camada de aparência, camada de interface, camada de fábrica abstrata, camada de entidade e camada de entidade podem ser consideradas como a camada de modelo nas três camadas.Pelo resultado, suas funções são semelhantes.
A camada de aparência é principalmente para separar a camada de IU e a camada BLL; a fábrica abstrata mais reflexão é principalmente para a conveniência de substituir o banco de dados, ao converter as classes na camada DAL para a interface na camada IDAL, de modo que camada pode ser chamada chamando a camada IDAL DAL; A camada de interface é principalmente para separar a camada BLL e a camada DAL.
Função de sete camadas
1. Camada de interface (IU): é usada principalmente para coletar os dados inseridos pelo usuário e, em seguida, passá-los para a camada de aparência e, em seguida, passá-los para a camada B para julgamento correspondente.
2. Camada de lógica de negócios (BLL): A camada B é usada principalmente para julgamento lógico, chamando o método na fábrica para criar a interface correspondente.
3. Camada de acesso a dados (DAL): implementa a interface definida pela camada de interface.
4. Fachada: O objetivo de usar a camada de aparência é reduzir o acoplamento entre as camadas U e B. A conexão entre as camadas U e B só precisa passar pela interface da camada de fachada, e a camada U não precisa para conhecer a camada B. Quais são os métodos internos. A camada de aparência recebe os dados da camada U e, a seguir, chama o método da camada B para verificar as informações.
5. Factory: Através do arquivo de configuração e abstract factory, podemos alterar o banco de dados sem alterar o código, alterando o valor no arquivo de configuração. O trabalho que o Factory precisa concluir é definir uma interface para chamar a camada de interface para realizar a transferência de dados entre a camada BLL e a camada DAL.
6. Camada de interface (IDAL): A camada de interface é usada para definir uma interface unificada e desacoplar as camadas B e D.
7. Entidade: Igual à camada de entidade nas três camadas, é usada principalmente para transferir dados entre as camadas.
O diagrama de pacote acima explicou a relação de referência muito claramente, então comece a praticar, e ao mesmo tempo lembre o mesmo que as três camadas, preste atenção se a nomenclatura é consistente.
Arquivo de configuração do APP:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key ="ConnStr" value="server=.; database=Login;User ID = sa ; Password=123456"/>
<!--<add key ="DB" value="DAL" />-->
<!--SqlServer是D层类的前缀,用来区别使用的是什么类型的数据库-->
<add key="DB" value="Login.DAL"/>
</appSettings>
</configuration>
Camada de entidade Entidade:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.Entity
{
public class UserInfo
{
private string _userName;
private string _passWord;
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
public string Password
{
get { return _passWord; }
set { _passWord = value; }
}
}
}
Camada de acesso a dados DAL:
Classe LoginDAL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using DAL;
namespace Login.DAL
{
public class LoginDAL:Login.IDAL.LoginIDAL
{
public DataTable SelectUser(Entity.UserInfo userInfo)
{
CommandType Text = 0;
SqlHelper sqlhelper = new SqlHelper();
SqlParameter[] sqlParams = { new SqlParameter("@UserName", userInfo.UserName), new SqlParameter("@PassWord", userInfo.Password) };
string sql = @"SELECT ID,UserName,Password,Email FROM USERS WHERE UserName=@UserName AND Password=@Password";
DataTable table = sqlhelper.ExecuteQuery(sql, sqlParams,Text);
return table;
}
}
}
Classe SQLHelper:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
namespace DAL
{
//数据访问层,数据操作类
public class SqlHelper
{
//定义数据库连接操作,指定在数据库上操作的类型
private SqlConnection conn = null;
private SqlCommand cmd = null;
private SqlDataReader sdr = null;
//数据库连接
public SqlHelper()
{
string connStr = ConfigurationManager.AppSettings["connStr"];
conn = new SqlConnection(connStr);
}
private SqlConnection GetConn()
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
return conn;
}
///<summary>
///执行不带参数的数据库操作或者存储过程
/// 增删改查操作
/// 返回受影响的行数
///</summary>
public int ExecuteNonQuery(string cmdText, CommandType ct)
{
int res;
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
res = cmd.ExecuteNonQuery();
if (conn.State == System.Data.ConnectionState.Open)
{
conn.Close();
}
return res;
}
//执行带参数的数据库操作或者存储过程
public int ExecuteNonQuery(string cmdText, SqlParameter[] paras, CommandType ct)
{
int res;
using (cmd = new SqlCommand(cmdText, GetConn()))
{
cmd.CommandType = ct;
cmd.Parameters.AddRange(paras);
res = cmd.ExecuteNonQuery();
}
return res;
}
//执行不带参数的SqL查询语句或者存储过程
public DataTable ExecuteQuery(string cmdText, CommandType ct)
{
DataTable dt = new DataTable();
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
using (sdr = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection))
{
dt.Load(sdr);
}
return dt;
}
//执行带参数的SQL查询语句或存储过程
public DataTable ExecuteQuery(string cmdText, SqlParameter[] paras, CommandType ct)
{
DataTable dt = new DataTable();
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
cmd.Parameters.AddRange(paras);
using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
dt.Load(sdr);
}
return dt;
}
}
}
Camada de lógica de negócios BLL:
Classe LoginBLL:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Data;
namespace Login.BLL
{
public class LoginBLL
{
public bool UserBLL(Entity.UserInfo userInfo)
{
Login.Factory.LoginFactory fact = new Login.Factory.LoginFactory();
IDAL.LoginIDAL idal = fact.CreateUser();//调用工厂方法创建接口
DataTable table = idal.SelectUser(userInfo);//接收D层返回值
Boolean flag;
if (table.Rows.Count == 0)
{
flag = false;
}
else
{
flag = true;
}
return flag;
}
}
}
Fachada:
Classe LoginFacade:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.Facade
{
public class LoginFacade
{
public Boolean SelectUser(Entity.UserInfo userInfo)
{
bool flag;
Login.BLL.LoginBLL userBLL = new Login.BLL.LoginBLL();
flag = userBLL.UserBLL(userInfo);
return flag;
}
}
}
Camada de fábrica abstrata Fábrica:
Classe LoginFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;//对配置文件的引用
using System.Reflection;//对反射的引用
using System.IO;
namespace Login.Factory
{
public class LoginFactory
{
//数据程序集名称,命名空间(DAL)
string AssemblyName = "Login.DAL";
//接收来自配置文件的数据,这里是接收D层类名的前缀,用来区别数据库类型
string StrDB = System.Configuration.ConfigurationManager.AppSettings["DB"];
public IDAL.LoginIDAL CreateUser()
{
//字符串拼接,这样写就能准确获取D层的具体某个类
string ClassName = StrDB +"."+ "LoginDAL";
//定义接口类型idal,来接收返回值
Login.IDAL.LoginIDAL idal = (Login.IDAL.LoginIDAL)Assembly.Load(StrDB).CreateInstance(ClassName);//反射加工厂的应用---------idal返回值为空
return idal;
}
}
}
Camada de interface IDAL:
Tipo de loginIDAL:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using Login.Entity;
namespace Login.IDAL
{
public interface LoginIDAL
{
//接口函数,判断要登陆的用户名是否在数据表中存在
DataTable SelectUser(UserInfo user);
}
}
Camada de interface da IU:
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;
namespace LoginUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
string UserName = txtUserName.Text.Trim();
string Password = txtPassword.Text;
//验证是否为空
if (txtUserName.Text == string.Empty)
{
MessageBox.Show("请输入账号!", "登录");
return;
}
else
{
if (txtPassword.Text == string .Empty)
{
MessageBox.Show("请输入密码!", "登录");
return;
}
//#region 登录
try
{
Login.Facade.LoginFacade fLogin = new Login.Facade.LoginFacade();//实例化外观
//Facade.LoginFacade fLogin = new Facade.LoginFacade();//实例化外观
Login.Entity.UserInfo user = new Login.Entity.UserInfo();
//Entity.UserInfo user = new Entity.UserInfo();
//调用外观的方法,返回给user
user.UserName = Convert.ToString(txtUserName.Text.Trim());
user.Password = Convert.ToString(txtPassword.Text);
Boolean flag = false;
flag = fLogin.SelectUser(user);
if (flag != false)
{
MessageBox.Show("登录成功!");
}
else
{
MessageBox.Show("密码或者用户名错误");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
}