在c#中实现3层架构

架构

介绍
这篇文章讨论如何在c#中实现3层架构,使用MS Access数据库存储数据。在此,我在3层架构中实现一个小型的可复用的组件保存客户数据。并提供添加,更新,查找客户数据的功能。

背景

首先,我介绍一些3层架构的理论知识。简单说明:什么是3层架构?3层架构的优点是什么?

什么是3层架构?

3层架构是一种“客户端-服务器”架构,在此架构中用户接口,商业逻辑,数据保存以及数据访问被设计为独立的模块。主要有3个层面,第一层(表现层,GUI层),第二层(商业对象,商业逻辑层),第三层(数据访问层)。这些层可以单独开发,单独测试。

为什么要把程序代码分为3层,把用户接口层,商业逻辑层,数据访问层分离有许多的优点。

 在快速开发中重用商业逻辑组件,我们已经在系统中实现添加,更新,删除,查找客户数据的组件。这个组件已经开发并且测试通过,我们可以在其他要保存客户数据的项目中使用这个组件。

 系统比较容易迁移,商业逻辑层与数据访问层是分离的,修改数据访问层不会影响到商业逻辑层。系统如果从用SQL Server存储数据迁移到用Oracle存储数据,并不需要修改商业逻辑层组件和GUI组件

 系统容易修改,假如在商业层有一个小小的修改,我们不需要在用户的机器上重装整个系统。我们只需要更新商业逻辑组件就可以了。

 应用程序开发人员可以并行,独立的开发单独的层。

 代码

 这个组件有3层,第一个层或者称为GUI层用form实现,叫做FrmGUI。第二层或者称为商业逻辑层,叫做BOCustomer,是Bussniess Object Customer的缩写。最后是第三层或者称为数据层,叫做DACustomer,是Data Access Customer的缩写。为了方便我把三个层编译到一个项目中。

 用户接口层

   下面是用户接口成的一段代码,我只选取了调用商业逻辑层的一部分代码。

//This function get the details from the user via GUI

//tier and calls the Add method of business logic layer.

private void cmdAdd_Click(object sender, System.EventArgs e)

{

      try

      {

            cus = new BOCustomer();

            cus.cusID=txtID.Text.ToString();

            cus.LName = txtLName.Text.ToString();

            cus.FName = txtFName.Text.ToString();

            cus.Tel= txtTel.Text.ToString();

            cus.Address = txtAddress.Text.ToString();

            cus.Add();

      }

      catch(Exception err)

      {

            MessageBox.Show(err.Message.ToString());

      }

}

//This function gets the ID from the user and finds the

//customer details and return the details in the form of

//a dataset via busniss object layer. Then it loops through

//the content of the dataset and fills the controls.

private void cmdFind_Click(object sender, System.EventArgs e)

{

      try

      {

            String cusID = txtID.Text.ToString();

                 

            BOCustomer thisCus = new BOCustomer();

                 

            DataSet ds = thisCus.Find(cusID);

            DataRow row;

            row = ds.Tables[0].Rows[0];

            //via looping

            foreach(DataRow rows in ds.Tables[0].Rows )

            {

               txtFName.Text = rows["CUS_F_NAME"].ToString();

               txtLName.Text = rows["CUS_L_NAME"].ToString();

               txtAddress.Text = rows["CUS_ADDRESS"].ToString();

               txtTel.Text = rows["CUS_TEL"].ToString();

           }

      }

      catch (Exception err)

      {

            MessageBox.Show(err.Message.ToString());

      }

}

//this function used to update the customer details.

private void cmdUpdate_Click(object sender,

                                 System.EventArgs e)

{

      try

      {

            cus = new BOCustomer();

            cus.cusID=txtID.Text.ToString();

            cus.LName = txtLName.Text.ToString();

            cus.FName = txtFName.Text.ToString();

            cus.Tel= txtTel.Text.ToString();

            cus.Address = txtAddress.Text.ToString();

            cus.Update();

      }

      catch(Exception err)

      {

            MessageBox.Show(err.Message.ToString());

      }

}

商业逻辑层

下面是商业逻辑层的所有代码,主要包括定义customer对象的属性。但这仅仅是个虚构的customer对象,如果需要可以加入其他的属性。商业逻辑层还包括添加,更新,查找,等方法。

商业逻辑层是一个中间层,处于GUI层和数据访问层中间。他有一个指向数据访问层的引用cusData = new DACustomer().而且还引用了System.Data名字空间。商业逻辑层使用DataSet返回数据给GUI层。

using System;

using System.Data;

namespace _3tierarchitecture

{

      /// <SUMMARY>

      /// Summary description for BOCustomer.

      /// </SUMMARY>

     

      public class BOCustomer

      {

            //Customer properties

            private String fName;

            private String lName;

            private String cusId;

            private String address;

            private String tel;

            private DACustomer cusData;

       public BOCustomer()

       {

            //An instance of the Data access layer!

             cusData = new DACustomer();

         }  

            /// <SUMMARY>

            /// Property FirstName (String)

            /// </SUMMARY>

            public String FName

            {

     

                  get

                  {

                        return this.fName;

                  }

                  set

                  {

                        try

                        {

                              this.fName = value;

                              if (this.fName == "")

                              {

                                    throw new Exception(

                                      "Please provide first name ...");

                              }

                        }

                        catch(Exception e)

                        {

                              throw new Exception(e.Message.ToString());

                        }

                  }

            }

            /// <SUMMARY>

            /// Property LastName (String)

            /// </SUMMARY>

            public String LName

            {

                  get

                  {

                        return this.lName;

                  }

                  set

                  {

                        //could be more checkings here eg revmove ' chars

                        //change to proper case

                        //blah blah

                        this.lName = value;

                        if (this.LName == "")

                        {

                              throw new Exception("Please provide name ...");

                        }

                  }

            }

            

            /// <SUMMARY>

            /// Property Customer ID (String)

            /// </SUMMARY>

            public String cusID

            {

                  get

                  {

                        return this.cusId;

                  }

                  set

                  {

                        this.cusId = value;

                        if (this.cusID == "")

                        {

                              throw new Exception("Please provide ID ...");

                        }

                  }

            }

            /// <SUMMARY>

            /// Property Address (String)

            /// </SUMMARY>

            public String Address

            {

                  get

                  {

                        return this.address;

                  }

                  set

                  {

                        this.address = value;

                        if (this.Address == "")

                        {

                              throw new Exception("Please provide address ...");

                        }

                  }

            }

            /// <SUMMARY>

            /// Property Telephone (String)

            /// </SUMMARY>

            public String Tel

            {

                  get

                  {

                        return this.tel;

                  }

                  set

                  {

                        this.tel = value;

                        if (this.Tel == "")

                        {

                              throw new Exception("Please provide Tel ...");

                        }

                  }

            }

            /// <SUMMARY>

            /// Function Add new customer. Calls

            /// the function in Data layer.

            /// </SUMMARY>

            public void Add()

            {

                  cusData.Add(this);

            }

            /// <SUMMARY>

            /// Function Update customer details.

            /// Calls the function in Data layer.

            /// </SUMMARY>

            public void Update()

            {

                  cusData.Update(this);

            }

            /// <SUMMARY>

            /// Function Find customer. Calls the

            /// function in Data layer.

            /// It returns the details of the customer using

            /// customer ID via a Dataset to GUI tier.

            /// </SUMMARY>

            public DataSet Find(String str)

            {

                  if (str == "")

                      throw new Exception("Please provide ID to search");

                     

                  DataSet data = null;

                  data = cusData.Find(str);

                  return data;

            }

      }

}

数据访问层

 数据层包括处理MS Access数据库的细节。所有这些细节都是透明的,不会影响到商业逻辑层。数据访问层有个指向商业逻辑层的引用BOCustomer cus。为了应用方便并且支持其他数据库。
using System;

using System.Data.OleDb;

using System.Data;

namespace _3tierarchitecture

{

    /// <SUMMARY>

    /// Summary description for DACustomer.

    /// </SUMMARY>

    public class DACustomer

    {

        private OleDbConnection cnn;

        //change connection string as per the

        //folder you unzip the files

        private const string CnnStr =

          "Provider=Microsoft.Jet.OLEDB.4.0;Data " +

          "Source= D:\\Rahman_Backup\\Programming\\" +

             "Csharp\\3tierarchitecture\\customer.mdb;";

        //local variables

        private String strTable="";

        private String strFields="";

        private String strValues="";

        private String insertStr="";

       

        //this needs to be changed based on customer

        //table fields' Name of the database!

        private const String thisTable = "tblCustomer";

        private const String cus_ID = "CUS_ID";

        private const String cus_LName = "CUS_L_NAME";

        private const String cus_FName = "CUS_F_NAME";

        private const String cus_Tel = "CUS_TEL";

        private const String cus_Address = "CUS_ADDRESS";

        public DACustomer()

        {

        }

       

        public DACustomer(BOCustomer cus)

        {

            // A reference of the business object class

        }

       

        //standard dataset function that adds a new customer

        public void Add(BOCustomer cus)

        {

            String str = BuildAddString(cus);

           

            OpenCnn();

            //Open command option - cnn parameter is imporant

            OleDbCommand cmd = new OleDbCommand(str,cnn);

            //execute connection

            cmd.ExecuteNonQuery();

           

            // close connection

            CloseCnn();

           

        }

       

        //standard dataset function that updates

        //details of a customer based on ID

        public void Update(BOCustomer cus)

        {

            OpenCnn();

           

            String selectStr = "UPDATE " + thisTable +

                " set " + cus_LName + " = '" + cus.LName + "'" +

                ", " + cus_FName + " = '" + cus.FName + "'" +

                ", " + cus_Address + " = '" + cus.Address + "'" +

                ", " + cus_Tel + " = '" + cus.Tel + "'" +

                " where cus_ID = '" + cus.cusID + "'";

            OleDbCommand cmd = new OleDbCommand(selectStr,cnn);

            cmd.ExecuteNonQuery();

           

            CloseCnn();

        }

       

        //standard dataset function that finds and

        //return the detail of a customer in a dataset

        public DataSet Find(String argStr)

        {

            DataSet ds=null;

            try

            {

                OpenCnn();

           

                String selectStr = "select * from " + thisTable +

                              " where cus_ID = '" + argStr + "'";

                OleDbDataAdapter da =

                       new OleDbDataAdapter(selectStr,cnn);

                ds = new DataSet();

                da.Fill(ds,thisTable);

           

                CloseCnn();

               

            }

            catch(Exception e)

            {

                String Str = e.Message;

            }

            return ds;

        }

        private void OpenCnn()

        {

            // initialise connection

            String cnnStr = CnnStr;

            cnn = new OleDbConnection(cnnStr);

            // open connection

            cnn.Open();

        }

        private void CloseCnn()

        {

            // 5- step five

            cnn.Close();

        }

       

        // just a supporting function that builds

        // and return the insert string for dataset.

        private String BuildAddString(BOCustomer cus)

        {

            // these are the constants as

            // set in the top of this module.

            strTable="Insert into " + thisTable;

            strFields=" (" + cus_ID +

            "," + cus_LName +

            "," + cus_FName +

            "," + cus_Address +

            "," + cus_Tel + ")";

           

            //these are the attributes of the

            //customer business object.

            strValues= " Values ( '" + cus.cusID +

            "' , '" + cus.LName +

            "' , '" + cus.FName +

            "' , '" + cus.Address +

            "' , '" + cus.Tel + "' )";

            insertStr = strTable + strFields + strValues;

           

            return insertStr;

           

       }

    }

}

时间: 2024-10-31 18:46:46

在c#中实现3层架构的相关文章

艾伟_转载:在C#中实现3层架构

这篇文章讨论如何在c#中实现3层架构,使用MS Access数据库存储数据.在此,我在3层架构中实现一个小型的可复用的组件保存客户数据.并提供添加,更新,查找客户数据的功能. 背景 首先,我介绍一些3层架构的理论知识.简单说明:什么是3层架构?3层架构的优点是什么? 什么是3层架构? 3层架构是一种"客户端-服务器"架构,在此架构中用户接口,商业逻辑,数据保存以及数据访问被设计为独立的模块.主要有3个层面,第一层(表现层,GUI层),第二层(商业对象,商业逻辑层),第三层(数据访问层)

ASP.NET MVC5网站开发之展示层架构(五)_实用技巧

展示层由Ninesky.Web项目实现,负责网站内容的显示,项目包含Member和Control两个区域. Member区域实现网站内容的管理,Control区域实现网站系统管理.结构.功能图如下:  一.Member区域 1.添加Member区域 Ninesky.Web[右键]-> 添加->区域 . 在弹出的添加区域对话框输入区域名称:Member,完成区域添加. 2.添加Home控制器 Ninesky.Web->Areas->Member->Controllers[右键]

用好Visual Studio 2010进行层架构设计

微软已经把VS 2010(Visual Studio 2010 Ultimate)功能融入到软件应用生命周期管理(ALM)中.在架构设计方面则是通过新的架构层关系图(Architecture Layer Diagram),以图形化的方式描述系统架构,从而使得项目中的技术人员或非技术人员都能以模型透过图形化的方式进行协作与设计,以及定义企业的系统功能. Visual Studio 2010提供针对不同功能层面的分析工具来辅助程序代码进行逆向工程.Layer Diagram可从高阶面来看架构:Arc

基于C/S的4层架构 —— ESFramework介绍之(6)

    ESFramework的4层结构的4层分别是:客户端(Client).应用服务器(AS).功能服务器(FS).数据库服务器.它们之间的联系图示意如下:     FS (FunctionServer),功能服务器,处理并且仅处理所有的功能性请求,不参与用户管理.状态保持等,提供最纯粹的功能服务.    AS (ApplicationServer),应用服务器,转发所有的功能请求给FS,并处理所有的非功能请求,并管理终端用户.进行状态保持.日志记录等.    上图中的功能服务器FS的个数可能

一起谈.NET技术,用好Visual Studio 2010进行层架构设计

微软已经把VS 2010(Visual Studio 2010 Ultimate)功能融入到软件应用生命周期管理(ALM)中.在架构设计方面则是通过新的架构层关系图(Architecture Layer Diagram),以图形化的方式描述系统架构,从而使得项目中的技术人员或非技术人员都能以模型透过图形化的方式进行协作与设计,以及定义企业的系统功能. Visual Studio 2010提供针对不同功能层面的分析工具来辅助程序代码进行逆向工程.Layer Diagram可从高阶面来看架构:Arc

业务层架构模式

一:业务层架构模式概述 在三层架构中,业务层负责所有业务相关的工作,包括根据输入数据或已有数据进行计算,对从表示层输入的数据进行验证,以及根据从表示层接收的命令来确定应该调用哪些数据访问逻辑.对于应用系统来说,业务层主要维护业务逻辑,是系统的核心部分.因此,在应用系统开发时,业务层的开发是最为关键的. 业务层的架构模式有多种,最著名的就是以下两种 : 事务脚本模型(面向过程的设计) 领域模型(面向对象的设计)   二:事务脚本模型 事务脚本(Transaction Script)架构模型是按照传

在使用spring的过程中,service层写在配置文件中好呢还是注解配置好呢?

问题描述 在使用spring的过程中,service层写在配置文件中好呢还是注解配置好呢? 在使用spring的过程中,service层写在配置文件中好呢还是注解配置好呢?在配置文件中是这样的注解配置时这样的@Service(""userService"")说说理由哦. 解决方案 一般应用性开发使用注解就可以.它较xml配置方式的优势在于省去了xml复杂的配置,而且不需要维护两套内容(xml配置方式需要维护service类和xml文件).但是如果需要修改相关内容,注

[译] 理解 NodeJS 中基于事件驱动的架构

本文讲的是[译] 理解 NodeJS 中基于事件驱动的架构, 原文地址:Understanding Node.js Event-Driven Architecture 原文作者:Samer Buna 译文出自:掘金翻译计划 译者:刘德元 薛定谔的猫 校对者:bambooom zaraguo 理解 NodeJS 中基于事件驱动的架构 绝大部分 Node.js 对象,比如 HTTP 请求.响应以及"流",都使用了 eventEmitter 模块来支持监听和触发事件. 事件驱动最简单的形式是

工具类中调用dao层的方法,spring配置如何写

问题描述 工具类中调用dao层的方法,spring配置如何写 private Set readSensitiveWord() { Set set = new HashSet(); List list = sensitiveDao.findSensitive(); if(list.size()>0){ for(Sensitive s : list){ set.add(s); } } return set; } 在这个方法中我要调用dao层的方法findSensitive().sensitiveDa