前言

最近在进行三层的学习,刚开始实在是不明白三层是什么?为什么要分层?通过一段时间的学习了解了不少

目录

正文

三层有哪些?

为什么要使用三层?(来源于生活)

他们是如何关联、联系(UI—>BLL—>DAL)的?

 为什么他们都要引用Model层,有什么作用?

什么情况下需要使用?

实战演练

 ①、场景

②、项目素材

③、代码展示

Model层

UI层

BLL层

DAL层

④、顺序图展示


正文

三层有哪些?

1.UI(View),表示层。接收显示数据(接受用户输入数据、显示处理后的数据);

2.BLL(Business Logic Layer),业务逻辑层。数据处理和传递,如:逻辑判断、计算

3.DAL(Data Access Layer),数据访问层。与数据库打交道。访问数据库,对数据表进行Select,Insert,Update,Delete操作,并且将处理后的数据保存到数据库

                                                                                         image.png

为什么要使用三层?(来源于生活)

目的:高内聚,低耦合

耦合性:块间联系,模块间相互联系紧密程度的一种度量。模块间联系越紧密,耦合性越强,模块的独立性越差

内聚性:块内联系,一个模块内各元素(语句之间、程序段之间)联系的越紧密,他的内聚性越高

image.png

1.如果顾客感觉服务不好,就是服务员的问题;

如果顾客觉得这个菜不好吃,馊了,就是厨师的问题;

如果觉得今天菜买的不够新鲜,坏了,就是采购员的问题

2.如果服务员请假或离职了,就找另一个服务员顶替;如果厨师今天请假或离职了,就找其他厨师;如果采购员今天请假或离职了,就找其他的采购员。

各司其职,在其位,谋其政,行其权,尽其责

①、在某一层里面,语句联系越紧密,内聚越高。层与层之间联系越差,耦合性越弱,独立性就越强。

②、开发人员可以只关注整个结构中的其中一层,降低层与层之间的依赖。​任何一层发生变化都不会影响另外一层。

③、利于各层逻辑的复用(就像第一次机房里面的模块)

他们是如何关联、联系(UI—>BLL—>DAL)的?

通过变量或实体作为参数来进行传递

  image.png

在VS中的形式:

image.png

 为什么他们都要引用Model层,有什么作用?

Model:业务数据模型,为了在三层之间传送数据,将三层联系起来,在三层之间传递数据。独立于其他三个层次,不属于任何一个层次。

引用Model层可以实现数据的封装、业务逻辑的处理、解耦和重用、数据验证和安全性、数据传递和交互等功能。它是三层架构中重要的一层,可以提高代码的可维护性、可重用性和安全性

什么情况下需要使用?

需要:当业务复杂到一定程序,当数据存储到相应的数据库或者独立的数据存储介质情况下。业务访问访问脱离业务单独存在,业务脱离UI单独存在,UI只需要呼叫业务访问层就可以实现跟用户的交互!!

不需要:简单、没有真正的数据存储层


实战演练

 ①、场景

现有一个成绩系统,学生登录自己的用户名、密码即可进入系统查询相关成绩信息

②、项目素材

③、代码展示

Model层

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Login.Model
{
    public class UserInfo
    {
        private int id;                
        private string username;
        private string password;
        private string email;

        //将标中的每个字段抽取为类的字段,并封装成属性
        /// <summary>
        /// 用户id
        /// </summary>
        public int ID
        {
            get { return id; }
            set { id = value; }
        }

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName
        {
            get { return username; }
            set { username = value; }
        }

        /// <summary>
        /// 密码
        /// </summary>
        public string Password
        {
            get { return password; }
            set { password = value; }
        }

        /// <summary>
        /// 邮件地址
        /// </summary>
        public string Email
        {
            get { return email; }
            set { email = value; }
        }
    }
}

UI层

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;
using BLL;
using Model;

namespace UI
{
    public partial class LoginForm : Form
    {

        public LoginForm()
        {
            InitializeComponent();
        }

        #region 登录单击事件
        private void btnLogin_Click(object sender, EventArgs e)
        {
            //UI  层将用户输入数据传递给BLL层
            //第1步、定义两个变量用来接收用户输入的值           
            int userName = Convert.ToInt32(txtUserName.Text.Trim());  //变量,获取用户名
            string password = txtPassword.Text;                       //变量,获取密码,有可能password是个空格就不用trim了
            string msg = "";                                          //第2步、定义一个string类型变量,用来获取从BLL返回来的登陆提示信息


            BLL.LoginManagerBLL lmBLL = new BLL.LoginManagerBLL();   //第3步、实例化B层服务类
            Model.UserInfoEnity user = new Model.UserInfoEnity();    //第4步、实例化实体层对象user

            msg = lmBLL.UserLogin(userName, password, out msg);      //第5步、调用B层UserLogin方法,并把值传入B层,,将返回的提示符信息重新赋值给msg变量。

            MessageBox.Show(msg);                                    //第22步、BLL层返回业务层传递的数据给用户,弹出提示框            
        }
        #endregion
    }
}

BLL层

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL;
using Model;

namespace BLL
{
    public class LoginManagerBLL
    {
        public string UserLogin(int userName, string password, out string msg)
        {            
            UserDAL uDAL = new UserDAL();                                //第6步、实例化D层对象           
            bool result = uDAL.CheckUserByIdAndName(userName, password); //第7步、调用D层方法,并传参。定义一个bool类型变量
                                                                         //第19步、变量result,接收返回来的布尔类型值
            if (result)                                                  //第20步、判断,如果查询到用户信息
            {
                msg = "登陆成功";                                         //弹出提示信息                 
            }
            else
            {
                msg = "用户名或密码不正确,登陆失败";                       
            }
            return msg;                                                //第21步、UI层返回业务层传递的数据给用户
        }
    }
}
}

DAL层

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using Model;

namespace DAL
{
    public class UserDAL
    {
        public bool CheckUserByIdAndName(int userName, string password)
        {
            //有了using,connection就可以自动关闭了
            //实例化一个连接对象conn,并连接数据源DataSourceDAL
            bool flag = false;                                                        //第8步、定义一个标签变量
            using (SqlConnection conn = new SqlConnection(DataSourceDAL.Connstring))  //第9步、实例化连接对象conn并连接数据源
            {
                SqlCommand cmd = conn.CreateCommand();                                 //第10步、实例化执行对象cmd
                cmd.CommandText = @"select * from Users where ID=@ID and Password =@Password"; //第11步、要执行的SQL语句
                cmd.CommandType = CommandType.Text;                                            //第12步、要执行的SQL语句是Text文本类型的

                SqlParameter[] sqlparameters = new SqlParameter[]                              //第13步、定义一个参数数组,并给参数赋值
                {
                    new SqlParameter("@ID",userName),                                          //给参数赋值
                    new SqlParameter("@Password",password)
                };

                cmd.Parameters.AddRange(sqlparameters);                                        //第14步、添加数组
                conn.Open();                                                                   //第15步、打开连接
                SqlDataReader reader = cmd.ExecuteReader();                                    //第16步、执行对象,

                if (reader.Read())                                                            //第17步、逐条读取数据,如果有数据
                {
                    flag = true;                                                              //返回true,说明存在此管理员
                }
                return flag;                                                                  //第18步、返回标签
            }                                                       
        }
    }
}

④、顺序图展示

三层架构的优点:

  • 分离关注点:每个层都有明确的职责,使得代码更加清晰、易于理解和维护。
  • 可测试性:每个层都可以独立进行测试,提高了代码的可测试性。
  • 可扩展性:每个层都可以独立进行扩展,使得系统更容易进行功能的添加和修改。
  • 代码重用:每个层都可以独立进行重用,提高了代码的可重用性。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐