深入浅出三层架构

简介:

这几天看了不少三层架构的资料,整理整理

——故写篇博文谈谈自己的看法。

三层架构概念:

三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。区分层次的目的即为了“高内聚,低耦合”的思想,复杂项目不能把SQL语句直接写到程序里,不模块话,难以维护。应该采取三层架构。

1、表现层(UI):通俗讲就是展现给用户的界面,即用户在使用一个系统的时候他的所见所得。

2、业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。

3、数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、查找等。
 
简单的说,UI层调用BLL,BLL调用DAL,数据用Model进行传递,Model为各层之间架起了数据传输的桥梁。
参考模型:UI<-->Model<-->BLL<-->Model<-->DAL

传统的两层结构和三层架构之间的区别:

 
下面我以一个简单的例子来细数三层架构:

代码剖析:

  • 新建一个项目(Windows 窗体应用程序),再在根目录下新建3个文件夹,分别是Model,DAL,BLL。
  • 在Model下添加一个Person类
  • 在DAL下添加一个SQLHelper类和一个PersonDAL类。
  • 在BLL下添加PersonBLL类

Person.cs代码如下:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 三层架构Demo.Model
{
class Person
{
public int Id { get;set;}
public int Age { get; set; }
public string Name { get; set; }

}
}
复制代码



SQLHelper类,封装了数据库操作的方法:

SQLHelper.cs代码入下:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;

namespace 三层架构Demo.DAL
{
class SQLHelper
{
//public static readonly string connStr = System.Configuration.ConfigurationSettings.AppSettings["dbconnstr"];
//获得连接字符串
public static readonly string connStr =
ConfigurationManager.ConnectionStrings["dbconnstr"].ConnectionString;

///
/// 执行方法ExecuteNonQuery
///
///
要执行的sql语句
/// 参数数组
/// 受影响的行数
public static int ExecuteNonQuery( string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn= new SqlConnection (connStr))
{
conn.Open();
using (SqlCommand cmd= conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
int i=cmd.ExecuteNonQuery();
return i;
}
}
}

///
/// 执行ExecuteScalar() 返回第一行第一列数据
///
/// 要执行的sql语句
/// 参数数组
/// 返回第一行第一列数据
public static object ExecuteScalar( string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn= new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
return cmd.ExecuteScalar();
}
}
}

///
/// 执行ExecuteDataTable()方法
///
/// 要执行的Sql语句
/// 参数数组
/// 返回一个DataTable
public static DataTable ExecuteDataTable( string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn= new SqlConnection (connStr))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
using ( SqlDataAdapter adapter= new SqlDataAdapter (cmd))
{
DataTable dt = new DataTable();
adapter.Fill(dt);
return dt;
}
}
}
}

///
/// 执行ExecuteSqlDataReader()方法
///
/// 要执行的Sql语句
/// 参数数组
/// 返回一个SqlDataReader

public static SqlDataReader ExecuteSqlDataReader( string cmdText,
params SqlParameter[] parameters)
{
using (SqlConnection conn= new SqlConnection (connStr))
{
conn.Open();
using (SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = cmdText;
cmd.Parameters.AddRange(parameters);
return cmd.ExecuteReader();
}
}
}
}
}
复制代码

PersonDAL.cs代码如下:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 三层架构Demo.Model;
using System.Data.SqlClient;
using System.Data;

namespace 三层架构Demo.DAL
{
class PersonDAL
{
///
/// 返回一个新增对象的主键,设为自动增长
///
///

///
public int Addnew(Person model)
{
string sql = " insert into T_person(Age,Name) output inserted.id values(@Age,@Name) ";

object obj=
SQLHelper.ExecuteScalar(sql, new SqlParameter( " Age ",model.Age), new SqlParameter( " Name ",model.Name));
// Convert : 与 value 等效的 32 位有符号整数,如果 value 为 null,则为零。
return Convert.ToInt32(obj);
}
///
/// 删除数据
///
///
///
public int Delete( int id)
{
string sql = " delete form T_Person where Id=@Id ";
return SQLHelper.ExecuteNonQuery(sql, new SqlParameter( " Id ",id));
}
///
/// 修改数据
///
///
///
public int Update(Person model)
{
string sql = " update T_Person set Age=@Age,Name=@Name where Id=@Id ";
return SQLHelper.ExecuteNonQuery(sql, new SqlParameter( " Age ",model.Age), new SqlParameter( " Name ",model.Name),
new SqlParameter( " Id ",model.Id));
}

///
/// 查询数据
///
///
///
public Person Get( int id)
{
string sql= " select * from T_Person where Id=@Id ";
DataTable dt=SQLHelper.ExecuteDataTable(sql, new SqlParameter( " Id ",id));
if (dt.Rows.Count<= 0)
{
return null;
}
else if (dt.Rows.Count== 1)
{
Person model1 = new Person();
model1.Id = Convert.ToInt32(dt.Rows[ 0][ " Id "]);
model1.Name = Convert.ToString(dt.Rows[ 0][ " Name "]);
model1.Age = Convert.ToInt32(dt.Rows[ 0][ " Age "]);
return model1;
}
else // 以防意外情况
{
throw new Exception( " 数据库中有两条及以上重复数据 ");
}
}
///
/// 获取全部数据
///
///
public IEnumerable GetAll()
{
string sql = " select * from T_Person ";
DataTable dt = SQLHelper.ExecuteDataTable(sql);
List list = new List();
foreach (DataRow row in dt.Rows)
{
Person model = new Person();
model.Id = Convert.ToInt32(row[ " Id "]);
model.Name =Convert.ToString(row[ " Name "]);
model.Age = Convert.ToInt32(row[ " Age "]);
list.Add(model);
}
return list;
}
}
}
复制代码

 

进行逻辑判断的BLL层代码看似是这样的:

PersonBLL.cs代码如下:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 三层架构Demo.Model;
using 三层架构Demo.DAL;
using System.Data.SqlClient;
using System.Data;

namespace 三层架构Demo.BLL
{
class PersonBLL
{
public int Addnew(Person model)
{
return new PersonDAL().Addnew(model);
}

public int Delete(int id)
{
return new PersonDAL().Delete(id);
}

public int Update(Person model)
{
return new PersonDAL().Update(model);
}

public Person Get(int id)
{
return new PersonDAL().Get(id);
}

public IEnumerable GetAll()
{
return new PersonDAL().GetAll();
}


}
}
复制代码

 

UI层进行测试:

Form1.cs代码如下:

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using 三层架构Demo.Model;
using 三层架构Demo.DAL;
using 三层架构Demo.BLL;

namespace 三层架构Demo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//Person p1 = new Person();
//p1.Age = 22;
//p1.Name = "Eyes";
//int id=new PersonDAL().Addnew(p1);
//MessageBox.Show(id.ToString());

//PersonDAL p = new PersonDAL();
//Person a = p.Get(1);
//a.Name = "jack";
//MessageBox.Show(a.Name + "," + a.Age);
//p.Update(a);


//PersonBLL bll = new PersonBLL();
//Person p = bll.Get(1);
//p.Name = "Admin";
//MessageBox.Show(p.Name + "," + p.Age);
//bll.Update(p);

PersonBLL b = new PersonBLL();
List list = (List)b.GetAll();
foreach (Person item in list)
{
MessageBox.Show(item.Id+","+item.Name+","+item.Age);
}

}

private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = new PersonBLL().GetAll();
}
}
}
复制代码

 

总结:

 

优点

  1、开发人员可以只关注整个结构中的其中某一层;

  2、可以很容易的用新的实现来替换原有层次的实现;

  3、可以降低层与层之间的依赖;

  4、有利于标准化;

  5、利于各层逻辑的复用。

缺点

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

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

  3、增加了开发成本。






 
本博客为木宛城主原创,基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名木宛城主(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
分类: 架构思想
三层 架构 .Net

本文转自木宛城主博客园博客,原文链接:http://www.cnblogs.com/OceanEyes/archive/2012/02/10/SANCENG.html,如需转载请自行联系原作者
目录
相关文章
|
监控 Java 数据处理
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
2579 6
|
10月前
|
消息中间件 监控 Docker
Docker环境下快速部署RabbitMQ教程。
就这样,你成功地用魔法召唤出了RabbitMQ,还把它和你的应用程序连接了起来。现在,消息会像小溪流水一样,在你的系统中自由流淌。别忘了,兔子们不喜欢孤独,他们需要你细心的关怀,不时地监控它们,确保他们的世界运转得井井有条。
613 18
|
芯片 SoC 内存技术
全志H713红外IR遥控配置方法
这篇文章详细介绍了全志H713芯片平台配置红外遥控器的方法,包括获取遥控器规格、NEC协议的配置步骤、其他IR协议配置以及解决头码配置问题的方法。
1065 5
全志H713红外IR遥控配置方法
|
存储 大数据 关系型数据库
【数据库三大范式】让我们来聊一聊数据库的三大范式和反范式设计
数据库三大范式是指数据库设计中的规范化原则,它们分别是第一范式(1NF)第二范式(2NF)和第三范式(3NF)。第一范式(1NF)第二范式(2NF)第三范式(3NF)
|
安全 开发工具 Android开发
安卓与iOS系统的优缺点比较
【2月更文挑战第6天】 安卓和iOS是目前市场上最流行的两种操作系统。虽然它们都拥有自己的独特之处,但它们也有一些共同之处。本文将探讨这两种操作系统的优缺点,并对它们进行比较。
1071 5
|
SQL 运维 安全
WAF如何防御SQL注入?
【7月更文挑战第25天】WAF如何防御SQL注入?
1274 9
|
负载均衡 API 微服务
深入浅出:使用Python构建微服务架构
本文旨在为读者提供一个清晰、易懂的指南,介绍如何使用Python语言构建微服务架构。微服务架构作为一种现代软件开发实践,能够提高大型应用的可维护性和可扩展性。通过本文,我们将探索微服务的基本概念、优势以及如何利用Python的强大生态系统进行微服务的设计与实现。我们会通过一个简单实例,演示从零开始构建微服务的全过程,包括服务的划分、通信机制、以及如何利用容器技术(如Docker)进行部署。此外,文章还将讨论在微服务架构下的常见挑战和最佳实践,旨在为读者提供一份全面而深入的实用指南。
|
安全 Unix 网络安全
Permission Denied原因及解决方法
Permission Denied原因及解决方法
5943 0
|
API 网络架构 C++
Bito - 超越Copilot的一款神级插件
Bito - 超越Copilot的一款神级插件
491 0