前面介绍了三层的知识内容,这里介绍一下三层的代码内容,就以登陆窗体(C#语言)为例:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
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)
{
//IDbConnection conn = new SqlConnection("");
//IDbCommand cmd = conn.CreateCommand();
//cmd.CommandText = "Select UserName From USER WHERE...";
//cmd.ExecuteReader();
string userName = txtUserName.Text .Trim();
string password = txtPassword.Text;
Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();
Login.Model.UserInfo user= mgr.UserLogin(userName, password);
MessageBox.Show("UserName:" + user.UserName);
}
private void btnExit_Closing(object sender, EventArgs e)
{
if(MessageBox.Show ("确定退出?","退出登录",MessageBoxButtons.OKCancel ,MessageBoxIcon.Question ,MessageBoxDefaultButton.Button2)==DialogResult.OK)
{
this.Close();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.BLL
{
public class LoginManager
{
public Login.Model .UserInfo UserLogin(string userName,string password)
{
//throw new NotImplementedException();
DAL.UserDAO uDao = new Login.DAL.UserDAO();
Login.Model .UserInfo user=uDao.SelectUser(userName, password);
if (user != null) //login successfully
{
Login.DAL.ScoreDAO sDAO = new Login.DAL.ScoreDAO();
sDAO.UpdateScore(userName, 10);
return user;
}
else
{
throw new Exception("登陆失败");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.DAL
{
class DbUtil
{
public static string ConnString = @"Server=TGB;Database=Login;User ID=sa;Password=123456";
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
namespace Login.DAL
{
public class ScoreDAO
{
public void UpdateScore(string userName,int value)
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString ))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = @"INSERT INTO SCORES(UserName,Score) Values(@UserName,@Score)"; //注意规范“INSERT INTO 表名(列名) Values(@变量)”;如果主键不是自动递增,则需要添加
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Score", value));
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace Login.DAL
{
public class UserDAO
{
public Login.Model .UserInfo SelectUser(string userName,string password)
{
using(SqlConnection conn = new SqlConnection(DbUtil.ConnString)) //using链接数据库后自动关闭
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = @"SELECT ID,UserName,Password,Email FROM USERS WHERE UserName=@UserName AND Password=@Password";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@UserName", userName));
cmd.Parameters.Add(new SqlParameter("@Password", password));
conn.Open(); //由于链接以自动关闭,故需重新打开
SqlDataReader reader= cmd.ExecuteReader();
Login.Model.UserInfo user = null;
while (reader.Read ())
{
if(user==null)
{
user = new Login.Model.UserInfo();
}
user.ID = reader.GetInt32(0);
user.UserName = reader.GetString(1);
user.Password = reader.GetString(2); //not suggestion
if (!reader.IsDBNull(3)) //档数据内容为空时需判断是否空,否则会发生异常
{
user.Email = reader.GetString(3);
}
}
return user;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Login.Model
{
public class UserInfo
{
public int ID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Email { get; set; }
}
}
说到引用,在代码里要加入引用的命名空间,否则是不会引用成功的,当然,如果你是通过手动引用,则会自动加入命名空间,也就是说命名空间是一定要写出来的,例如:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
还有,包括些系统方法(非系统语言默认但存在的),也都需要有引用命名空间。例如链接数据库:
using System.Data;
using System.Data.SqlClient;
通过上面三层,我们了解到UI层、BLL层和DAL层之间还是存在强耦合,如果我要改变一层的内容,另一层可能就需要一起跟着改动,而这不符合我们所学的设计模式原则,故而才有了扩展七层的进步。例如我们将BLL层之间再进行细分,将算法单独取出来,这就用到了我们学过的设计模型之一工厂方法模型,建立一个算法工厂。在UI层和BLL层之间解耦和,在BLL层和DAL层之间解耦和,等等都可以将三层扩展成七层,也就实现了降低三层耦合性,从而使代码更优化,结构更简洁清晰。
对了,在这里我需要提一下:在C#编码中,引用时单方向的,而不能是互相都可以引用。例如上面的代码,UI层、BLL层和DAL层引用的Model层,而不能Model层也引用其他三层。同理,UI层引用了BLL层,BLL层引用了DAL层,而DAL层不能反过来引用BLL层,BLL层也不能反过来引用UI层。
针对具体的三层转换成七层的实现,待下一回合讲述,感谢您的阅读,也诚挚地邀您多多发表宝贵的意见!