三层这个阶段的学习主要是靠自学,但从网上找到的相关资料、博客都是零散的,没有体系。资料看了不少,但一直没有一个大概的轮廓。查到的资料都是理论性的,那怎样在具体的例子中实现分层呢?导图之后就是具体的小例子。
以初识三层中登录的小例子为例,来看看分层的具体应用吧。
主要步骤:用户在登录界面输入用户名和密码,并进行登录。若登录成功,弹出登录成功提示框,并增加相应的积分。若不成功,抛出登录失败。
1、U层:表现层,用户输入数据和指令,并最终显示出信息。
界面
namespace LoginUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//输入用户名和密码,单击登录按钮
private void button1_Click(object sender, EventArgs e)
{
string userName = textBox1.Text.Trim();
string password = textBox2.Text;
Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();
Login.Model01.UserInfo user = mgr.UserLogin(userName, password); //实例化对象
MessageBox.Show("登录用户:" + user.UserName);
}
}
}
2、B层:业务逻辑层,处理与业务相关的逻辑,把从U层传来的用户名和密码经过处理,传到D层作相应的数据处理。
namespace Login.BLL
{
//判断用户是否存在,若存在,登录成功并增加积分;若不存在,抛出异常。
public class LoginManager
{
public Login.Model01.UserInfo UserLogin(string userName, string password)
{
Login.DAL.UserDAO uDao = new Login.DAL .UserDAO();
Login.Model01 .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("登录失败。"); //异常处理
}
}
}
}
3、D层:数据访问层,执行与数据源相关的操作。在这里,包括DbUtil, ScoreDAO,UserDAO。
DbUtil负责打开数据库,访问数据库。
namespace Login.DAL
{
class DbUtil
{
public static string ConnString = @"Server=yang; Database=Login; User ID=sa; Password=123456";//yang为服务器地址,Login是数据库名称
}
}
UserDAO用来判断该用户名是否存在,密码是否正确。
namespace Login.DAL
{
public class UserDAO
{
public Login.Model01.UserInfo SelectUser(string userName, string password) //用户名和密码通过B层传到D层,在D层实现查找
{
using (SqlConnection conn = new SqlConnection(DbUtil.ConnString)) //建立一个sql连接,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.Model01.UserInfo user = null; //判断记录是否存在
while (reader.Read())
{
if (user == null)
{
user = new Login.Model01.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;
}
}
}
}
ScoreDAO负责当用户登录成功后,更新数据库中的积分。
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)";
cmd.Parameters.Add(new SqlParameter("@UserName", userName)); //Parameters添加记录
cmd.Parameters.Add(new SqlParameter("@Score", value));
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
}
4、实体类
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; }
}
}
这样,各层分工明确,职责清晰。既有利于合作开发,也大大降低了维护的成本和维护的时间。与我们第一次机房收费系统的登录界面相比,分层之后的登录界面就显得效果好多了。但是分层不是分的越多越好,过多的分层限制了开发人员与客户对系统的理解能力,限制了客户与开发人员的交流。分层越多的话,可靠性有时也是不稳定; 项目开发中实在是要具体分析,盲目套用耦合不降反升,效率不高反低,维护不便反繁。
分层不是目的,是软件发展的产物和毕竟之路。层化是把软件横向切了几刀,模块化是把软件纵向切了几刀。我们要灵活使用分层,更好的为我们服务。