【面向对象】初步接触三层架构

三层架构

三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer) 、业务逻辑层(Business Logic Layer) 、数据访问层(Data access layer) 。区分层次的目的即为了“高内聚低耦合”的思想。

在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。

微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。

三层原理

  • 3个层次中,系统主要功能和业务逻辑都在业务逻辑层进行处理。

  • 所谓三层体系结构,是在客户端与数据库之间加入了一个“中间层”,也叫组件层。

  • 这里所说的三层体系,不是指物理上的三层,不是简单地放置三台机器就是三层体系结构,也不仅仅有B/S应用才是三层体系结构,三层是指逻辑上的三层,即把这三个层放置到一台机器上。

  • 通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交互。

各层对比

各层作用重要性
UI层提供界面,输入输出指令或数据※※※※
业务层传达数据,分析结果※※※※※
数据层操纵数据库,增删改查※※※※

优缺点

优点

1.明确了“高内聚低耦合”的思想;

2.操作员只需要关注整个项目中的一层;

3.降低层与层之间的依赖;

4.有利于标准化;

5.利于各层逻辑的复用;

6.结构更加的明确;

7.在后期维护的时候,极大地降低了维护成本和维护时间;

缺点

  • 1、降低了系统的性能。

    这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

  • 2、有时会导致级联的修改。

    这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

  • 3、增加了开发成本。

    通过分层设计,就会增加各个部门的精英人数,更加细致的划分人员,使得开发费用增加。

例子展示

例子说明

利用三层实现以下功能:1.登陆窗体,判断登陆是否成功;2.登陆成功增加10点积分;

程序设计思考

  • 思考

要利用三层架构实现登陆窗体,首先要熟悉登陆的流程,要建立各个层,然后要确定每层的主要功能是什么,最后代码实现。

  • 登陆流程图

登陆流程图

关键代码展示

  • 首先要从UI层开始;
private void button1_Click(object sender, EventArgs e)
        {
            //传值,将两个text传给userName 和password。
            string userName = txtUserName.Text.Trim();
            string password = txtPassWord.Text;

            //实例化业务层
            Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();    //实例化一个业务层的LoginManager,用于判断逻辑
            Login.Model.UserInfo user = mgr.UserLogin(userName, password); //实例化一个业务层的Model,用于给userLogion赋值name,password。

            MessageBox.Show("登陆用户:"+userName );   //显示登录信息。
        }
  • 然后要到业务层,判断用户是否登陆成功;
//管理登录类,用于判断用户是否登陆成功。
    public class LoginManager    
    {   
        public Login.Model.UserInfo UserLogin(string userName, string password)    //UserLogin方法,判断登录信息是否正确
        {       
            Login.DAL.UserDAO uDao = new Login.DAL.UserDAO();     //实例化一个数据层登录
            Login.Model.UserInfo user= uDao.SelectUser(userName,password);  //实例化一个model,用于给数据层的Selectuser赋值。

            if (user != null)   //login successful
            {
                Login.DAL.ScoreDAO sDao = new Login.DAL.ScoreDAO();
                sDao.UpdateScore(userName, 10);  //增加积分
                return user;
            }
            else
            {
                throw  new Exception("登陆失败");
            }
        }
    }
  • 接下来是到数据层,判断用户名和密码是否正确;
public class UserDAO
    {
        public Login.Model .UserInfo SelectUser (string userName, string passWord)
        {
            //throw new NotImplementedException();   //返回bool值,判断是否登陆成功。
            using (SqlConnection conn=new SqlConnection (DBUtil .ConnString ))   //建立数据库连接。
            {
                #region  连接数据库,创建连接对象cmd,需要引用using System.Data.SqlClient;引用数据库命名空间。
                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));
                #endregion
                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);     //获取指定列的 32 位有符号整数形式的值
                    user.UserName = reader.GetString(1);
                    user.Password = reader.GetString(2);

                    if (!reader.IsDBNull(3))
                    {
                        user.Email = reader.GetString(3);
                    }
                }
                return user;   //很重要 
            }
        }
    }
  • 在数据层对比后,将结果返还给业务层,再传给UI层,UI层将结果输出给用户。如果成功,在业务层判断后,需要为此用户添加积分,就要再次到数据层,为用户增加积分;
public class ScoreDAO
    {
        public void UpdateScore(string userName, int value)   //更新积分的方法UpdateScore
        {
            using(SqlConnection conn=new SqlConnection (DBUtil .ConnString))
            {
                #region  连接数据库,创建连接对象cmd
                SqlCommand cmd = conn.CreateCommand();
                cmd .CommandText =@"INSERT INTO SCORE (UserName ,Score) Values(@UserName,@Score)";
                cmd.Parameters .Add (new SqlParameter ("@UserName",userName));
                cmd.Parameters .Add (new SqlParameter("@Score",value ));
                #endregion
                //打开数据库连接。
                conn.Open();
                //执行SQL句,返回受影响行数(判断执行SQL句是否成功)
                cmd.ExecuteNonQuery ();
            }
        }
    }
  • 温馨提示:在三层数据传递的过程中,会涉及到一个上传下蹦作用的实体,帮助我们传输数据;(具体作用看链接 [ 实体 ])
 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; }

    }
}

学习心得

刚刚接触了三层架构,初步感觉运用三层架构是比较麻烦的,但是从后期维护、长久的使用来想,三层确实是要发展的趋势。通过这个例子的学习,我也初步了解了实体的概念,很多情况下我们都需要开放自己,让自己接受新知识。加油吧!骚年!

更多了解:
【作者:王雷 http://blog.csdn.net/kisscatforever

评论 93
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你个佬六

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值