对于三层架构来讲,主要是使用设计模式的思想,对于项目的各个模块实现"高内聚,低耦合"的思想。这里就不作详细的介绍了,若是你们有兴趣,能够阅读软件工程和设计模式相关文章。mysql
对于三层架构来讲,就是使用类,把咱们在作项目的过程当中,可能须要反复操做数据库,反复的使用某个方法等等,可能就是操做的参数不一样。若是咱们若是在每次使用的时候,都去编写相应的代码,无疑会增长程序员的负担。因此,为了增长方法的重用,就把这些可以重用的方法抽象成类,以供程序员在其它地方能够调用。程序员
固然了,这也是面向对象的一部分。其中的三层所指的就是:①视图层(UI)②数据库访问层(DAL)③业务逻辑层(BLL)。固然了,还有所谓的第四层-实体层(model),这一层主要是在这三个层之间进行流动传递。可是为何不叫四层架构。。。缘由我也不知道,多是由于实体层是外在的能够根据须要会随时变化的(如:项目后续模块的添加等)。而其它三个层,若是搭建完后,能够做为框架来使用的。。。sql
1)首先仍是先来介绍一下实体层吧,就是咱们一般所说的model数据库
实体就是咱们在开发项目过程当中所要涉及的一些对象。把这些所要涉及的对象(如:新闻名称,新闻上传时间,供稿人,上传文件的名称等),都抽象成一个类。使用封装字段方法,咱们能够在视图层通(主要是视图层)过实例化对象的方法,来给咱们的对象的属性赋值。设计模式
简单的看一段代码吧,可能会可以更加的清楚,明白数组
- public class NewsModel
- {
-
- private int nNewsId;
-
- public int NNewsId
- {
- get { return nNewsId; }
- set { nNewsId = value; }
- }
-
-
- private string strNewsName;
-
- public string StrNewsName
- {
- get { return strNewsName; }
- set { strNewsName = value; }
- }
-
- }
这里的NewsModel就是一个关于新闻的实体类,其中声明了两个private的属性字段(必定要是private,防止非法赋值),使用public的构造函数,能够在外部给字段赋值。网络
下面的就是在视图层来实例化对象,根据须要来给字段赋值,看下面的一段代码:架构
- <span style="white-space:pre"> </span>NewsModel newModel = new NewsModel();
- newModel.StrNewsName = this.TextBox1.Text;
-
固然了,这仅仅是一段代码,其中并无给字段nNewsId赋值,由于我把它做为数据库的id地段,已经设置成自动增加。这样,就完成了视图层对实体层的调用。框架
2)数据库访问层函数
数据库库访问层,顾名思义,就是主要来完成对数据库的访问,等一系类的对数据库操做的类。为何要单独的把对数据库的操做抽象成一个单独的类,我我的理解是由于在整个项目的开发过程当中,不只仅须要一次访问数据库,而是须要屡次,若是每次都编写数据库访问代码的话,会增长程序员的我的工做量,并且对于代码的易用性和简洁性来讲确定是很是糟糕的。固然来可能还有其它的一些优势,我暂时尚未发现。
既然是对数据库的操做类,并且对数据库的操做,无非就是四种:增删改查。因此一个能提供增删改查的通用类是必不可少的。这就是咱们常常所说的,通用数据库访问类(不少的程序员都喜欢把这个类命名为SqlHelper,既然是名字,都是能够随意起的,只要不违反C#语法命名规范,固然这样命名也是有好处,就是可使其余程序员根据类的名称,大概判断出这个类是要干什么的)。
固然了,我此次作本身项目的时候,所写的数据库访问类就没有我上次看周金桥老师的书,而后模仿写的数据库访问类那么的复杂了(《【ASP.NET开发】ASP.NET对SQLServer的通用数据库访问类》)。固然了,我这里的数据库访问类,主要仍是为了简介,和易用,只要知足我本身当前项目的须要就能够了,不是每作一个项目,都要写一个功能全面的数据库访问类。
代码以下,请你们参考,更喜欢哪一个访问类,本身能够根据本身口味,或者须要,直接用也能够:
- public class SqlHelper
- {
-
- private static readonly string connectionString = ConfigurationManager.ConnectionStrings["strConnectionString"].ConnectionString;
-
-
-
-
-
-
-
- public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters)
- {
- using (SqlConnection con = new SqlConnection(connectionString))
- {
- con.Open();
- using (SqlCommand cmd = con.CreateCommand())
- {
- cmd.CommandText = sql;
- cmd.Parameters.AddRange(parameters);
- string str = sql;
- return cmd.ExecuteNonQuery();
-
- }
- }
- }
-
-
-
-
-
-
-
- public static int ExecuteScalar(string sql, params SqlParameter[] parameters)
- {
- using (SqlConnection con = new SqlConnection(connectionString))
- {
- con.Open();
- using (SqlCommand cmd = con.CreateCommand())
- {
- cmd.CommandText = sql;
- cmd.Parameters.AddRange(parameters);
- return Convert.ToInt32( cmd.ExecuteScalar());
- }
- }
- }
-
-
-
-
-
-
-
- public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
- {
- using (SqlConnection con = new SqlConnection(connectionString))
- {
- con.Open();
- using (SqlCommand cmd = con.CreateCommand())
- {
- cmd.CommandText = sql;
- cmd.Parameters.AddRange(parameters);
-
- SqlDataAdapter adapter = new SqlDataAdapter(cmd);
- DataTable dt = new DataTable();
- adapter.Fill(dt);
- return dt;
- }
- }
- }
- }
这样的类建立好之后,其余的须要访问数据库的类,就能够根据本身的须要,完成相应的增删改查的操做了。仍是用一段代码来演示吧:
- public class NewsDALL
- {
-
- public int AddNews(NewsModel model)
- {
- string sql = "insert into News (name,author,time,content,sort,isdelete) values(@name,@author,@time,@content,@sort,@isdelete)";
- 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));
- return nResult;
- }
-
-
- public int DeleteNew(int id)
- {
- string sql = "delete from News where id=@id";
- int nResult = SqlHelper.ExecuteNonQuery(sql, new SqlParameter("@id", id));
- return nResult;
- }
-
-
- public int UpdateNew(NewsModel model, int nID)
- {
- string sql = "update News set name=@name,time=@time,content=@content where id=" + nID;
- int nResult = SqlHelper.ExecuteNonQuery(sql, new SqlParameter("@name", model.StrNewsName), new SqlParameter("@time", model.StrAddTime), new SqlParameter("@content", model.StrNewsContent));
-
- return nResult;
- }
-
-
- public NewsModel GetNewsModel(int id)
- {
- string sql = "select * from News 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)
- {
- NewsModel newModel = new NewsModel();
- DataRow dr = dt.Rows[0];
- newModel.StrNewsName = dr["name"].ToString();
- newModel.StrNewsAuthor = dr["author"].ToString();
- newModel.StrAddTime = dr["time"].ToString();
- newModel.StrNewsContent = dr["content"].ToString();
- newModel.Sort = (int)dr["sort"];
-
- return newModel;
- }
- else
- {
- throw new Exception("出现异常!");
- }
- }
- }
这里的这个NewsDALL类,主要是来完成有关新闻须要对数据库的各类操做,固然了,这只是这个类的一部分,主要是来演示NewsDALL类怎样调用SqlHelper类中的方法,来完成对数据库的操做的。
3)接下来就是最后一层,业务逻辑层了。
业务逻辑层的话主要来处理视图层和数据库访问层之间的关系的。固然了,也能够直接在视图层调用数据库访问层,可是对于关系来讲可能会增长复杂性,因此前辈们就专门的抽象出来一个业务逻辑层,把全部的业务逻辑关系都在这一层处理清楚以后再,访问数据库访问层,进行对数据的操做。(固然这是我本身的理解,若是有什么不对的话,请你们指正)
在我此次的项目中,貌似个人这一层彻底是多余的,由于不须要什么太多的业务逻辑的处理,能够彻底在视图层直接访问数据库访问层的。
仍是使用代码说话吧,固然这个仍然是NewsBLL类代码的一部分:
- public class NewsBLL
- {
-
- public static int AddNew(NewsModel model)
- {
- NewsDALL newDALL = new NewsDALL();
- return newDALL.AddNews(model);
- }
-
-
- public static int DeleteNew(int i)
- {
- NewsDALL newDALL = new NewsDALL();
- return newDALL.DeleteNew(i);
- }
-
-
-
-
- public static NewsModel GetModel(int intSort)
- {
- NewsModel model = new NewsModel();
- if (intSort == 1)
- {
- model.StrNewSort1 = "学院新闻";
- model.StrNewSort2 = "";
- model.StrNewSort3 = "";
- }
- else if (intSort == 2)
- {
- model.StrNewSort1 = "公告通知";
- model.StrNewSort2 = "";
- model.StrNewSort3 = "";
- }
- ..........
-
- return model;
- }
- }
接下来就是在视图层来经过访问,业务逻辑层来和实体层,来玩成所须要的数据操做了。
仍是使用代码来描述吧,这个代码主要来完成对数据进行添加:
- public void InsertData()
- {
- NewsModel newModel = new NewsModel();
- newModel.StrNewsName = this.TextBox1.Text;
- newModel.StrNewsAuthor = this.TxtBoxAuthor.Text;
- newModel.StrAddTime = this.TxtDate.Text;
- newModel.StrNewsContent = Server.HtmlDecode(FCKeditor1.Value);
- newModel.Sort =Convert.ToInt32( this.DropDownList2.SelectedValue.ToString());
-
-
- int nResult= NewsBLL.AddNew(newModel);
- if (nResult != 0)
- {
- Response.Write("<script>alert('添加成功!')</script>");
- }
- else
- {
- Response.Write("<script>alert('添加失败!')</script>");
- }
- }
我之前本身作的图,被你们指出了不少的错误。因此,我就引用了网络上的一个图片来解释(若是侵害了您的版权,请您联系我)

据我本身的理解,三层架构能够算是一个团队项目开发的基本框架,在这个框架的基础上能够知足一些设计模式的须要。固然能够知足模块开发的须要。
总结:
对于我此次的开发项目来讲,收获仍是不少的,之前仅仅是知道有三层架构这个东西,也看书,照着别人的代码写过,可是却不能体会到这其中的真正意义。
优势:①使代码的重用更加的高了,不须要像之前作项目,每次在一个页面反复的编写操做数据库的代码,而使用三层架构的话,只须要把注意力放在业务逻辑层 的业务逻辑的处理和数据库访问层的sql语句的编写。
②代码的整洁性,和易用性更加的高了。由于不一样的操做都分别放在了不一样的层,因此代码逻辑更加清晰,若是作好注释的话,别人可以更加清楚的理解 编写者的意图。
③可扩展型更加的高了,根据须要在不一样的层编写代码,而后调用就能够了。
④很是利于团队开发。
固然了,三层架构的有点不只仅有这些,否则也不会成为如今企业开发的基本框架,这只不过是我在开发中明显的发现的优势,拿出来跟你们分享一下。
缺点:①就是性能上确定比之前直接在相应的页面编写数据库操做代码上有点下降。可是这个彻底是能够接受的,何况,对于我如今的水平就是代码质量上可定还 有待提升,有更大的优化空间。
②就是在个人项目中,我以为最大的浪费就是能够在视图层直接访问数据库访问层,由于要处理的业务逻辑实在是很少,因此仍是有点代码冗余吧。因此, 之后仍是要跟据本身项目的须要,来灵活的使用,不必定要按照规定必须这样作。