.NET三层架构简单解析

对于三层架构来说,主要是使用设计模式的思想,对于项目的各个模块实现"高内聚,低耦合"的思想。这里就不做详细的介绍了,如果大家有兴趣,可以阅读软件工程和设计模式相关文章。

对于三层架构来说,就是使用类,把我们在做项目的过程中,可能需要反复操作数据库,反复的使用某个方法等等,可能就是操作的参数不同。如果我们如果在每次使用的时候,都去编写相应的代码,无疑会增加程序员的负担。所以,为了增加方法的重用,就把这些能够重用的方法抽象成类,以供程序员在其它地方可以调用。

当然了,这也是面向对象的一部分。其中的三层所指的就是:①视图层(UI)②数据库访问层(DAL)③业务逻辑层(BLL)。当然了,还有所谓的第四层-实体层(model),这一层主要是在这三个层之间进行流动传递。但是为什么不叫四层架构。。。原因我也不知道,可能是因为实体层是外在的可以根据需要会随时变化的(如:项目后续模块的添加等)。而其它三个层,如果搭建完后,可以作为框架来使用的。。。

1)首先还是先来介绍一下实体层吧,就是我们通常所说的model

实体就是我们在开发项目过程中所要涉及的一些对象。把这些所要涉及的对象(如:新闻名称,新闻上传时间,供稿人,上传文件的名称等),都抽象成一个类。使用封装字段方法,我们可以在视图层通(主要是视图层)过实例化对象的方法,来给我们的对象的属性赋值。

简单的看一段代码吧,可能会能够更加的清楚,明白

[csharp] view plain copy

  1. public class NewsModel
  2. {
  3. //新闻编号
  4. private int nNewsId;
  5. public int NNewsId
  6. {
  7. get { return nNewsId; }
  8. set { nNewsId = value; }
  9. }
  10. //新闻名称
  11. private string strNewsName;
  12. public string StrNewsName
  13. {
  14. get { return strNewsName; }
  15. set { strNewsName = value; }
  16. }
  17. }

这里的NewsModel就是一个关于新闻的实体类,其中声明了两个private的属性字段(一定要是private,防止非法赋值),使用public的构造函数,可以在外部给字段赋值。

下面的就是在视图层来实例化对象,根据需要来给字段赋值,看下面的一段代码:

[csharp] view plain copy

  1. <span style="white-space:pre">  </span>NewsModel newModel = new NewsModel();
  2. newModel.StrNewsName = this.TextBox1.Text;

当然了,这仅仅是一段代码,其中并没有给字段nNewsId赋值,因为我把它作为数据库的id地段,已经设置成自动增长。这样,就完成了视图层对实体层的调用。

2)数据库访问层

数据库库访问层,顾名思义,就是主要来完成对数据库的访问,等一系类的对数据库操作的类。为什么要单独的把对数据库的操作抽象成一个单独的类,我个人理解是因为在整个项目的开发过程中,不仅仅需要一次访问数据库,而是需要多次,如果每次都编写数据库访问代码的话,会增加程序员的个人工作量,而且对于代码的易用性和简洁性来说肯定是非常糟糕的。当然来可能还有其它的一些优点,我暂时还没有发现。

既然是对数据库的操作类,而且对数据库的操作,无非就是四种:增删改查。所以一个能提供增删改查的通用类是必不可少的。这就是我们经常所说的,通用数据库访问类(很多的程序员都喜欢把这个类命名为SqlHelper,既然是名字,都是可以随意起的,只要不违反C#语法命名规范,当然这样命名也是有好处,就是可以使其他程序员根据类的名称,大概判断出这个类是要干什么的)。

当然了,我这次做自己项目的时候,所写的数据库访问类就没有我上次看周金桥老师的书,然后模仿写的数据库访问类那么的复杂了(《【ASP.NET开发】ASP.NET对SQLServer的通用数据库访问类》)。当然了,我这里的数据库访问类,主要还是为了简介,和易用,只要满足我自己当前项目的需要就可以了,不是每做一个项目,都要写一个功能全面的数据库访问类。

代码如下,请大家参考,更喜欢哪个访问类,自己可以根据自己口味,或者需要,直接用也可以:

[csharp] view plain copy

  1. /// <summary>
  2. ///创建一个SqlHelper的数据库访问通用类,完成对数据库的所有操作
  3. /// </summary>
  4. public class SqlHelper
  5. {
  6. //定义数据库的连接字符串
  7. private static readonly string connectionString = ConfigurationManager.ConnectionStrings["strConnectionString"].ConnectionString;
  8. /// <summary>
  9. /// 创建方法,完成对数据库的非查询的操作
  10. /// </summary>
  11. /// <param name="sql">sql语句</param>
  12. /// <param name="parameters">传入的参数</param>
  13. /// <returns></returns>
  14. public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters)
  15. {
  16. using (SqlConnection con = new SqlConnection(connectionString))
  17. {
  18. con.Open();
  19. using (SqlCommand cmd = con.CreateCommand())
  20. {
  21. cmd.CommandText = sql;
  22. cmd.Parameters.AddRange(parameters);
  23. string str = sql;
  24. return cmd.ExecuteNonQuery();
  25. }
  26. }
  27. }
  28. /// <summary>
  29. /// 完成查询的结果值
  30. /// </summary>
  31. /// <param name="sql">sql语句</param>
  32. /// <param name="parameters">传入的参数数组</param>
  33. /// <returns></returns>
  34. public static int ExecuteScalar(string sql, params SqlParameter[] parameters)
  35. {
  36. using (SqlConnection con = new SqlConnection(connectionString))
  37. {
  38. con.Open();
  39. using (SqlCommand cmd = con.CreateCommand())
  40. {
  41. cmd.CommandText = sql;
  42. cmd.Parameters.AddRange(parameters);
  43. return Convert.ToInt32( cmd.ExecuteScalar());
  44. }
  45. }
  46. }
  47. /// <summary>
  48. /// 主要执行查询操作
  49. /// </summary>
  50. /// <param name="sql">执行的sql语句</param>
  51. /// <param name="parameters">参数数组</param>
  52. /// <returns></returns>
  53. public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
  54. {
  55. using (SqlConnection con = new SqlConnection(connectionString))
  56. {
  57. con.Open();
  58. using (SqlCommand cmd = con.CreateCommand())
  59. {
  60. cmd.CommandText = sql;
  61. cmd.Parameters.AddRange(parameters);
  62. SqlDataAdapter adapter = new SqlDataAdapter(cmd);
  63. DataTable dt = new DataTable();
  64. adapter.Fill(dt);
  65. return dt;
  66. }
  67. }
  68. }
  69. }

这样的类创建好以后,其他的需要访问数据库的类,就可以根据自己的需要,完成相应的增删改查的操作了。还是用一段代码来演示吧:

[csharp] view plain copy

  1. /// <summary>
  2. ///NewsDALL 的摘要说明
  3. /// </summary>
  4. public class NewsDALL
  5. {
  6. //向数据库中插入新闻
  7. public int AddNews(NewsModel model)
  8. {
  9. string sql = "insert into News (name,author,time,content,sort,isdelete) values(@name,@author,@time,@content,@sort,@isdelete)";
  10. int nResult = SqlHelper.ExecuteNonQuery(sql, new SqlParameter("@name", model.StrNewsName), new SqlParameter("@author",model.StrNewsAuthor),new SqlParameter("@time", model.StrAddTime), new SqlParameter("@content", model.StrNewsContent), new SqlParameter("@sort", model.Sort), new SqlParameter("@isdelete", model.IsDelete1));
  11. return nResult;
  12. }
  13. //执行数据库的删除操作
  14. public int DeleteNew(int id)
  15. {
  16. string sql = "delete from News where [email protected]";
  17. int nResult = SqlHelper.ExecuteNonQuery(sql, new SqlParameter("@id", id));
  18. return nResult;
  19. }
  20. //执行数据库的更新操作
  21. public int UpdateNew(NewsModel model, int nID)
  22. {
  23. string sql = "update News set [email protected],[email protected],[email protected] where id=" + nID;
  24. int nResult = SqlHelper.ExecuteNonQuery(sql, new SqlParameter("@name", model.StrNewsName), new SqlParameter("@time", model.StrAddTime), new SqlParameter("@content", model.StrNewsContent));
  25. return nResult;
  26. }
  27. //执行数据库的查询操作
  28. public NewsModel GetNewsModel(int id)//声明一次从数据库中读取新闻的条数
  29. {
  30. string sql = "select * from News where [email protected]";
  31. DataTable dt = SqlHelper.ExecuteDataTable(sql, new SqlParameter("@id", id));
  32. if (dt.Rows.Count <= 0)
  33. {
  34. return null;
  35. }
  36. else if (dt.Rows.Count == 1)
  37. {
  38. NewsModel newModel = new NewsModel();
  39. DataRow dr = dt.Rows[0];
  40. newModel.StrNewsName = dr["name"].ToString();
  41. newModel.StrNewsAuthor = dr["author"].ToString();
  42. newModel.StrAddTime = dr["time"].ToString();
  43. newModel.StrNewsContent = dr["content"].ToString();
  44. newModel.Sort = (int)dr["sort"];
  45. return newModel;
  46. }
  47. else
  48. {
  49. throw new Exception("出现异常!");
  50. }
  51. }
  52. }

这里的这个NewsDALL类,主要是来完成有关新闻需要对数据库的各种操作,当然了,这只是这个类的一部分,主要是来演示NewsDALL类怎样调用SqlHelper类中的方法,来完成对数据库的操作的。

3)接下来就是最后一层,业务逻辑层了。

业务逻辑层的话主要来处理视图层和数据库访问层之间的关系的。当然了,也可以直接在视图层调用数据库访问层,但是对于关系来说可能会增加复杂性,所以前辈们就专门的抽象出来一个业务逻辑层,把所有的业务逻辑关系都在这一层处理清楚之后再,访问数据库访问层,进行对数据的操作。(当然这是我自己的理解,如果有什么不对的话,请大家指正)

在我这次的项目中,貌似我的这一层完全是多余的,因为不需要什么太多的业务逻辑的处理,可以完全在视图层直接访问数据库访问层的。

还是使用代码说话吧,当然这个仍然是NewsBLL类代码的一部分:

[csharp] view plain copy

  1. /// <summary>
  2. ///业务逻辑层主要处理视图层和数据库访问直接的关系
  3. /// </summary>
  4. public class NewsBLL
  5. {
  6. //完成对数据库的添加
  7. public static int AddNew(NewsModel model)
  8. {
  9. NewsDALL newDALL = new NewsDALL();
  10. return newDALL.AddNews(model);
  11. }
  12. //完成对数据的删除
  13. public static int DeleteNew(int i)
  14. {
  15. NewsDALL newDALL = new NewsDALL();
  16. return newDALL.DeleteNew(i);
  17. }
  18. //返回一个新闻分类的对象
  19. public static NewsModel GetModel(int intSort)
  20. {
  21. NewsModel model = new NewsModel();
  22. if (intSort == 1)
  23. {
  24. model.StrNewSort1 = "学院新闻";
  25. model.StrNewSort2 = "";
  26. model.StrNewSort3 = "";
  27. }
  28. else if (intSort == 2)
  29. {
  30. model.StrNewSort1 = "公告通知";
  31. model.StrNewSort2 = "";
  32. model.StrNewSort3 = "";
  33. }
  34. ..........
  35. return model;
  36. }
  37. }

接下来就是在视图层来通过访问,业务逻辑层来和实体层,来玩成所需要的数据操作了。

还是使用代码来描述吧,这个代码主要来完成对数据进行添加:

[csharp] view plain copy

  1. public void InsertData()
  2. {
  3. NewsModel newModel = new NewsModel();
  4. newModel.StrNewsName = this.TextBox1.Text;
  5. newModel.StrNewsAuthor = this.TxtBoxAuthor.Text;
  6. newModel.StrAddTime = this.TxtDate.Text;
  7. newModel.StrNewsContent = Server.HtmlDecode(FCKeditor1.Value);
  8. newModel.Sort =Convert.ToInt32( this.DropDownList2.SelectedValue.ToString());
  9. //NewsBLL newBLL = new NewsBLL();
  10. int nResult= NewsBLL.AddNew(newModel);
  11. if (nResult != 0)
  12. {
  13. Response.Write("<script>alert(‘添加成功!‘)</script>");
  14. }
  15. else
  16. {
  17. Response.Write("<script>alert(‘添加失败!‘)</script>");
  18. }
  19. }

我以前自己做的图,被大家指出了很多的错误。所以,我就引用了网络上的一个图片来解释(如果侵害了您的版权,请您联系我)

据我自己的理解,三层架构可以算是一个团队项目开发的基本框架,在这个框架的基础上可以满足一些设计模式的需要。当然可以满足模块开发的需要。

总结:

对于我这次的开发项目来说,收获还是很多的,以前仅仅是知道有三层架构这个东西,也看书,照着别人的代码写过,但是却不能体会到这其中的真正意义。

优点:①使代码的重用更加的高了,不需要像以前做项目,每次在一个页面反复的编写操作数据库的代码,而使用三层架构的话,只需要把注意力放在业务逻辑层     的业务逻辑的处理和数据库访问层的sql语句的编写。

②代码的整洁性,和易用性更加的高了。因为不同的操作都分别放在了不同的层,所以代码逻辑更加清晰,如果做好注释的话,别人能够更加清楚的理解    编写者的意图。

③可扩展型更加的高了,根据需要在不同的层编写代码,然后调用就可以了。

④非常利于团队开发。

当然了,三层架构的有点不仅仅有这些,不然也不会成为现在企业开发的基本框架,这只不过是我在开发中明显的发现的优点,拿出来跟大家分享一下。

缺点:①就是性能上肯定比以前直接在相应的页面编写数据库操作代码上有点降低。但是这个完全是可以接受的,况且,对于我现在的水平就是代码质量上可定还     有待提高,有更大的优化空间。

②就是在我的项目中,我觉得最大的浪费就是可以在视图层直接访问数据库访问层,因为要处理的业务逻辑实在是不多,所以还是有点代码冗余吧。所以,     以后还是要跟据自己项目的需要,来灵活的使用,不一定要按照规定必须这样做。

时间: 2024-12-13 02:46:58

.NET三层架构简单解析的相关文章

分享基于EF+WCF的通用三层架构及解析

本项目结合EF 4.3及WCF实现了经典三层架构,各层面向接口,WCF实现SOA,Repository封装调用,在此基础上实现了WCFContext,动态服务调用及一个分页的实例. 1. 项目架构图: 2. 项目解决方案: 在传统的三层架构上增加了WcfService(服务端),WcfClientProxy(客户端服务调用),及WcfExtension(一些扩展) 3. Wcf Service的实现: 工厂实现了RemoteServiceFactory(用于远程调用)和RefServiceFac

delphi 三层架构简单例(转)

所谓三层: (1) 客户端 (2) 服务器端 (3) 数据库 在数据访问时,使得客户端必须通过服务器来访问数据库.提高了系统的安全性. 在Delphi中可以使用Socket或者Dcom来连接他们相互间的通讯.如果使用Scocket在系统使用时必须提供Scocket连接器,而Dcom则不用.客户端和服务器的连接需要Broker来联系.环境为winxp sp2 + delphi 7 + db7.(MSSQL2000)创建过程:1.请不要新建application.file-new-activex-a

三层架构简单代码描述

/// <summary> /// UI层的简单代码 /// </summary> void LoadStudentInfo() { BLL.PersonManager bllperson=new BLL.PersonManager(); //实例化BLL逻辑处理层 List<MODEL.Person> list = bllperson.BllStudentInfo(false); //接受从BLL层传回的返回值 this.dgvStudent.DataSource =

源码学习之Spring (系统架构简单解析)

Spring Framework 系统架构总览图 Spring Framework的模块依赖关系图 Spring Framework各个模块功能说明 Spring核心模块 模块名称 主要功能 Spring-core 依赖注入IOC和DI的基本实现 Spring-beans Bean工厂与Bean的装配 Spring-context 定义基础的Spring的Context上下文即IOC容器 Spring-context-support 对Spring IOC容器的扩展支持,以及IOC的子容器 Sp

三层架构简单实例【转】

原文发布时间为:2009-05-17 -- 来源于本人的百度文章 [由搬家工具导入] http://dev.csdn.net/author/gongchl2006/c9ce459daf3240aaa3d7e30dc32bed55.html

Asp.Net之三层架构

三层架构之理论: 通常意义上讲的三层架构就是将整个项目应用划分为:表现层(UI),业务逻辑层(BLL),数据访问层(DAL).与传统的二层架构的区别在于在用户界面(UI)和数据库服务器之间,添加中间层.而中间层又可划分为业务逻辑层(BLL),数据访问层(DAL)和数据对象模型层(Model).其中的数据对象模型层(Model)可以把表当做一个对象来处理,充分体现了面向对象的思想.三层架构因为"高内聚,低耦合"的特性,更利于 系统的设计和开发,同时为可能的变更提供了更小的单元,有利于系统

浅谈.NET,C#三层架构(自己总结)

 三层架构 常见架构: 三层(经典) MVC MVVM MVP 开发中常见的23种设计模式: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 设计模式的六大原则 1.开闭原则 2.里氏代换原则 3.依赖倒转原则 4.接

解析三层架构

引言: 大家都很清楚,去饭店吃饭,服务员只管接待客人,出事只管烹炒客人要的美食,采购员只管按客人需求采购肉.海鲜.蔬菜,他们各司其职.共同协作为客人提供美食. 三层的特点: 我们现在讲的三层架构,就是用这样工作的,他们三者中任何依着发生变化时都不会影响到其他两者的正常工作,so体现了三层的"高内聚,低耦合"的特点. 三层具体的描述: 从图中我们可以看到三层分别为:表达层(UI.用户界面层).业务逻辑层(BLL).数据访问层(DAL).简单地说一下他们的作用:UI:为用户提供交互操作界面

WPF MVVM 架构 Step By Step(2)(简单的三层架构示例及粘合代码GLUE code)

我们第一步就是去了解三层架构和问题然后去看MVVM是怎么去解决这些问题的. 现在,感觉和事实是完全不同的两个东西.当你看到三层架构的框图的时候,你会觉得每层的职责被分配的很好.但是当你你真的去写代码的时候你会发现其实一些层被迫去做本不应该他们做的额外的事情(违反了SOLID原则的S). 这个额外的工作就是在UI-Model和Model-Data access之间的代码.让我们就把这些代码称为“GLUE”代码.有两种主要的逻辑会造成“GLUE”代码(也许我知道的并不够多,其他的可以自己发现): 1