三层浅析及示例分析



什么是三层结构?所谓三层结构,不是物理上的三层划分,也不是简单的模块划分,而是逻辑上的三层,是在客户端和数据库访问之间加入了一个中间层,形成逻辑三层结构。

三层都是哪三层?它们的作用是什么?三层结构包含:表示层UI,业务逻辑层BLL,数据访问层DAL。1 显示层,就是软件的显示部分,主要是客户端,通常表现为WEB或窗体。主要功能:接受用户输入信息、显示系统输出信息、为用户提供一个交互界面。 2 业务逻辑层,系统主要功能部分,主要处理软件的业务逻辑,处理数据。 3 数据访问层,用于对数据库的操作,但不是数据库。

为什么要使用三层?设计模式告诉我们,软件设计开发要遵循开放--封闭原则,也就是说一款软件可以增加功能或代码,但是不能修改。使用三层结构以前,显示层、业务逻辑层、数据访问层都是耦合在一起的,如果我们需要变动客户端的内容,那么业务逻辑层就必须要改动,这是不安全的,所以我们需要把业务逻辑层单独处理,以减少它们之间的耦合。

以一个简单的登录示例来介绍三层的具体实现。看一下三层之间的关系图:

三层之间通过传递参数进行联系,如果参数过多,会使程序变得复杂化,这里我们引入实体来进行参数传递,同时数据库应该独立于数据访问层而存在,关系图需要改进,改进后的关系图如下:

(sqlhelper用于封装数据库连接语句,属于DAL层):

主窗体展示:

看一下各层的代码是如何实现各自功能的。U层代码:

[csharp] view plaincopyprint?

  1. namespace LoginUI
  2. {
  3. public partial class Form1 : Form
  4. {
  5. public Form1()
  6. {
  7. InitializeComponent();
  8. }
  9. private void btnOK_Click(object sender, EventArgs e)     //双击事件
  10. {
  11. Login.Model.UserInfo user1 = new Login.Model.UserInfo();        //使用实体传递数据
  12. user1.UserName = txtUserName.Text.Trim();
  13. user1.Password = txtPassword.Text.Trim();
  14. Login.BLL.LoginManager mgr = new Login.BLL.LoginManager();          //定义一个业务逻辑类
  15. Login.Model.UserInfo user4 = mgr.UserLogin(user1);      //定义实体存放登录结果(逻辑层比较结果)
  16. if (user4 == null)
  17. {
  18. MessageBox.Show("信息不正确");               //账号或密码不正确
  19. }
  20. else
  21. {
  22. MessageBox.Show("登录用户" + user1.UserName);   //登录
  23. }
  24. }
  25. }
  26. }

U层代码要实现两个功能,获得用户输入信息和显示系统输出信息,我们使用user1获得用户输入信息,使用user4获得B层的下层反馈信息,并且最后显示系统登录内容。U层没有任何的系统逻辑事物处理,也没有和数据库直接联系,降低了系统耦合度。

D层代码:

[csharp] view plaincopyprint?

  1. namespace Login.DAO
  2. {
  3. public class UserDAO             //用户数据操作类
  4. {
  5. public Login.Model.UserInfo  SelectUser(Login.Model.UserInfo user1)         //使用user1为参数连接数据库
  6. {
  7. string ConnString = @"Server=GE-PC;Database=Login;User=sa;Password=123456;";        //数据库连接字段
  8. using (SqlConnection conn = new SqlConnection (ConnString ))               //连接数据库
  9. {
  10. SqlCommand cmd = conn.CreateCommand();                              //
  11. cmd.CommandText = @"SELECT UserName, PassWord
  12. FROM USERS
  13. WHERE [email protected] AND [email protected]";
  14. cmd.CommandType = CommandType.Text;                             //
  15. cmd.Parameters.Add(new SqlParameter ("@UserName",user1.UserName));       //用户名
  16. cmd.Parameters.Add(new SqlParameter ("@Password",user1.Password));         //密码
  17. conn.Open();
  18. SqlDataReader reader = cmd.ExecuteReader();                         //
  19. Login.Model.UserInfo user2 = new Login.Model.UserInfo();            //连接数据库获得数据放到user2
  20. while(reader.Read())                    //
  21. {
  22. user2.UserName = reader.GetString(0).ToString().Trim();              //
  23. user2.Password = reader.GetString(1).ToString().Trim ();
  24. }
  25. return user2;                          //返回user2
  26. }
  27. }
  28. }
  29. }

D层代码主要功能是根据上层需要,连接数据库,操作数据库返回信息。这一层我们使用user2存放数据库信息并且把数据返回上一层,这里也没有任何的系统业务逻辑处理,只有对数据库操作。

最后看看B层是如何实现系统功能的:

[csharp] view plaincopyprint?

  1. namespace Login.BLL
  2. {
  3. public class LoginManager
  4. {
  5. public UserInfo UserLogin(Login.Model.UserInfo user1)
  6. {
  7. Login.DAO.UserDAO uDao = new Login.DAO.UserDAO();              //实例化用户数据操作类
  8. Login.Model.UserInfo user3 = uDao.SelectUser(user1);        //
  9. if (user3.UserName!=user1.UserName ||user3.Password!=user1.Password)             //判断账号密码是否正确
  10. {
  11. return null;          //信息不正确
  12. }
  13. else
  14. {
  15. return user3;           //返回数据库内容
  16. }
  17. }
  18. }
  19. }

B层主要就是实现系统的逻辑功能,这里使用U层的user1来存放登录的用户名和密码,使用user3来存放数据库中的用户名和密码,然后判断是否相同,实现登录功能,最后把判断结构返回到U层来显示出来。

运行结果:


         三层解决了数据显示和数据库的耦合问题,使软件的可维护性和灵活性增强。但是三层的使用,是系统更加复杂,对软件的有效性提出了考研。三层不是万能的,需要谨慎使用。

三层浅析及示例分析,布布扣,bubuko.com

时间: 2024-10-09 13:32:52

三层浅析及示例分析的相关文章

EF浅析及示例分析

数据作为软件的重要组成部分,它的存储和传递是每个软件必须考虑的事情.EF作为web应用程序开发过程中常用的数据处理解决方案,它是如何工作的,它的特点是什么?本文就此做个简单介绍. 最开始的时候,数据量比较小,并且没有涉及到数据库,我们使用变量作为载体,保存和传递数据,使用作用域的方式来界定变量的作用范围:这种方式的坏处就是,每个数据都需要一个变量,并且我们需要了解每个变量的作用域才能正确的使用它们. 接触到数据库以后,变量已经不能满足大批量数据的存储和传递,这时候DataTable表和实体出现了

EF浅析及示例分析2

上一篇博客我们提到了EntityFrameWork的使用好处和创建方法,这篇博客,继续讨论EntityFrameWork的使用.我们从EntityFrameWork的结构和使用两方面来讨论. 我们使用mvc模式来完成示例代码.上篇博客使用DBfirst生成模型结构如下图: 使用DBFirst生成的实体模型是一个以.edmx结尾的文件,展开这个文件,会看到一下这张图的四个文件..Context.tt文件中存放的是整个实体的信息. Blog.tt文件中存放的是模型中各个子实体的内容.如下图所示: 好

Unity Surface Shader 示例分析

对于Unity中的表面着色器(Surface Shader),它的代码整体结构如下所示: Shader "name" { Properties { // 第一部分 } SubShader { // 第二部分 } Fallback "Diffuse" // 第三部分 } 第一部分 Properties 数据块 它的作用是充当数据的接口,将外部的数据(资源)引入进来,以供着色器内部使用.在这里,我们可以定义的数据类型如下所示: (1) _MainTex ( "

RPM安装包-Spec文件参数详解与示例分析

spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件. 1.Spec文件参数 spec文件包含建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个目录下.这个文件一般分为如下的几节: (1) Preamle(序言) 序言包含用户请求包的信息时所显示的内容.它可以包含包的功能描述.包的软件版本.版权信息和所属的包组等.Summary 是一行关于该软件包的描述,Name 是该软件包的基名,Version 是该软件的版本号,Release 是 RP

smartjs - DataManager 场景示例分析 - 数据懒加载

发一张policy的参数图设置图: 场景1 - 数据的懒加载/延迟加载 在很多时候,为了提高网页的加载速度,减少不必要的开销,会将页面的数据拆分成几个部分,首先加载呈现可视区域内的数据,然后剩下来的会在需要的时候在进行加载. 而这种按需加载的数据又分为两种: 1.按照需要进行加载:可以是由某个动作触发来引起,比如:tab,查看更多等: 2.采用缓存的方式:对后续动作的预知,提前将后续的数据加载进来,放入到缓存中:等需要的时候能提供快速的响应:比如:很多igrid的滚动分页 那么来看一下在data

ngRx 官方示例分析 - 3. reducers

上一篇:ngRx 官方示例分析 - 2. Action 管理 这里我们讨论 reducer. 如果你注意的化,会看到再不同的 Action 定义文件中,导出的 String Literal Type 名称都是 Actions ,在导入的时候,同时导入同名的类型就是问题了.这里首先使用了 import as 语法进行重命名. import * as book from '../actions/book'; import * as collection from '../actions/collec

Android涂鸦技术及刮刮乐示例分析

概述: 很早之前就想研究一下Android中的涂鸦,其实也说不上是研究了,毕竟都是一些相对比较简单的知识点.下面就对基于画布(Canvas)和触摸事件(onTouchEvent)来实现涂鸦和刮刮乐. 参考: http://blog.csdn.net/lmj623565791/article/details/40162163 此人的博客的确很好,想学习的同学也可以去参考一下这个大牛的其他博客. http://blog.csdn.net/t12x3456/article/details/104329

Wait示例分析

wait方法使"当前线程"进入阻塞(等待)状态. 示例分析: public class TestWait { public static void main(String[] args) throws InterruptedException { Thread t = new MyThread("t1"); synchronized (t){ //main线程持有t对象的锁 System.err.println(Thread.currentThread().getN

【Big Data - Hadoop - MapReduce】初学Hadoop之图解MapReduce与WordCount示例分析

Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算. HDFS是Google File System(GFS)的开源实现. MapReduce是Google MapReduce的开源实现. HDFS和MapReduce实现是完全分离的,并不是没有HDFS就不能MapReduce运算. 本文主要参考了以下三篇博客学习整理而成. 1. Hadoop示例程序WordCount详解及实例 2. hadoop 学习笔