C#版机房重构——三层登录

前言

        光总结了C#三层登录出现的问题,还没有真正总结过三层登录实例,近来敲机房的七层登录,可谓是问题重重,当初自以为三层理解的很透彻了,现在看来还差的很多,我需要用总结来沉淀一下自己,让自己的心不那么浮躁。

三层

        简单来说,三层有别于之前有VB敲的小例子的是,三层非常好的解除了各个层之间的耦合,为以后的维护提供了极大的便利。

各个层之间的关系

U层:用户接触的层,准确来说,用户仅仅接触了一个U层。用于收集用户输入的信息以及用户的操作。
B层:根据U层用户输入的信息及操作和D层数据返回的信息,进行逻辑判断。
D层:连接数据库,接受B层消息,将用户需要的数据从数据库提取出来,返回到B层进行逻辑判断。

它们之间的引用关系为:U层引用B层,B层引用D层,各个层都引用实体层。用丹姐的包图来美化一下:

C#版机房重构——三层登录_第1张图片

代码

U层

        UI层很简单,就是将用户的操作传给B层。

namespace UI
{
    public partial class Login : Form
    {
        public Login()
        {
            InitializeComponent();
        }
        private void btnOk_Click(object sender, EventArgs e)
        {
            string UserID = txtUserID.Text.Trim();//赋值
            string PassWord = txtPassWord.Text;
            string msg;//定义变量
            msg = "";
            //Model.Gobal.user  = txtUserID.Text;

            BLL.LoginManager Agr = new BLL.LoginManager();//实例化B层
            #region//验证是否为空
            bool ey = Agr.Empty(UserID, PassWord);
            if (ey == false) { MessageBox.Show("请填写完整信息。"); return; }
            #endregion
            #region//登录
            Model.UserInfo User = Agr.UserLogin(UserID, PassWord,out msg);
            MessageBox.Show(msg);
            if (msg=="登录成功。")
            { 
                Model.Gobal.level = User.Level;
                #endregion
                机房收费系统 jf = new 机房收费系统();
                机房收费系统.isRunMain = true;
                jf.Show();
                this.Close();
            }
            else
            {
                txtUserID.Text = "";
                txtPassWord.Text = "";
                txtUserID.Focus();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
}


B层

        BLL层相对复杂一点,就是将U层传来的参数或D层返回的值进行逻辑判断,给出正确的操作。

namespace BLL
{
    public class LoginManager
    {
        public Model.UserInfo UserLogin(string UserID,string PassWord,out string msg)
        {
            DAL.UserDAO uDao = new DAL.UserDAO();//引用D层的UserDAO类
            Model.UserInfo User = uDao.SelectUser(UserID, PassWord);//引用实体层的SelectUser方法
            if(User!=null)
            {
                //return User;//将实体user返回到U层
                msg = "登录成功。";
            }
            else
            {
                //throw new Exception("登录失败。");
                msg="登录失败。";//在这如果用上面这个注释掉的语句的话,输入正确用户名密码没有关系,如果输入错误的很弹出一个非常不友好的错误提示,这在我的C#机房登录问题中有总结。
            }
            return User;
        }
        public bool Empty(string UserID,string PassWord)//这就是验证框是是否为空的代码,我是在B层判断完返回一个bool给U层的。
        {
            if (UserID == "" || PassWord == "") { return false; }
            else { return true; }
        }
    }
}

D层

        DAL层主要用到的就是连接数据库,让后对数据库中的数据进行一些简单的操作后返回给B层。对于B层引用的那个DbUtil.ConnString是在D层另外一个类里面定义的

namespace DAL
{
    class DbUtil
    {
        public static string ConnString = @"Server=XX;Database=你的数据库名字;User ID=**;Password=***";//链接数据库的字符串
    }
}

        接下来是D层

namespace DAL
{
    public class UserDAO
    {
        public Model.UserInfo SelectUser(string UserID, string PassWord)//声明引用了Model层的userInfo类的SelectUser方法
        {
            using (SqlConnection conn = new SqlConnection(DbUtil.ConnString))//引用连接数据库的字符串,连接数据库
            {
                SqlCommand cmd = conn.CreateCommand();//定义命令语句
                cmd.CommandText = @"SELECT * FROM T_USERS WHERE UserID=@UserID AND PassWord=@PassWord";
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.Add(new SqlParameter("@UserID", UserID)); //为参数@UserID赋值
                cmd.Parameters.Add(new SqlParameter("@PassWord", PassWord)); //为参数@PassWord赋值
                 
                conn.Open();//打开数据库连接
                SqlDataReader Reader = cmd.ExecuteReader();

                Model.UserInfo User = null;
                while (Reader.Read())
                {
                    if (User == null)
                    {
                        User = new Model.UserInfo();
                    }
                    User.UserID = Reader.GetString(0);//给实体层的属性写入数据
                    User.PassWord = Reader.GetString(1);
                    User.Level = Reader.GetString(2);
                    User.Status = Reader.GetInt16(3);
                    User.Head = Reader.GetString(4);
                }
                return User;//将实体user返回到B层
            }
        }
    }
}


实体层

        实体层主要用于在三个层中传递实体,比如该版登录返回的类型就是实体。实体没什么好说的,用到哪个参数就在实体中创建就行,需要注意的就是实体类里面是直接对应到数据库表的,你定义的数据类型要和表中类型相一致才行。

namespace Model
{
    public class UserInfo
    {
        public string UserID { get; set; }
        public string PassWord { get; set; }
        public string Level { get; set; }
        public Int16 Status { get; set; }
        public string Head { get; set; }
    }
}

总结

        三层的登录和七层的登录,对比VB敲的一层机房收费系统,其实就是把类与类之间的耦合一步步变小,达到一个相对完美,符合对扩展开放,对修改关闭的原则的过程,无非就是写代码的时候看似麻烦了一点,明明可以U层直接从数据库访问数据的却非要经过那么多层,传递那么多参数,但是这在以后的维护中起到了决定性的作用。站在一个高处去看七层,其实就是把以前的一步到位,转换成参数一步步传下去的过程。

        不管是VB机房,三层机房,还是七层机房,刚开始都觉得很难,后来理清楚一条线就简单了,一气呵成,现在敲七层,觉得根本不是人脑子能想出来的东西,回头看看三层,在看看VB版,它们是我一步步由难到易过来的,克服了重重困难,我相信我的七层也会在我的努力下变得简单。


你可能感兴趣的:(C#,三层)