C#中实现三层架构

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

背景

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


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


为什么要把程序代码分为3层。把用户接口层,商业逻辑层,数据访问层分离有许多的优点。
在快速开发中重用商业逻辑组件,我们已经在系统中实现添加,更新,删除,查找客户数据的组件。这个组件已经开发并且测试通过,我们可以在其他要保存客户数据的项目中使用这个组件。
系统比较容易迁移,商业逻辑层与数据访问层是分离的,修改数据访问层不会影响到商业逻辑层。系统如果从用SQL Server存储数据迁移到用Oracle存储数据,并不需要修改商业逻辑层组件和GUI组件
系统容易修改,假如在商业层有一个小小的修改,我们不需要在用户的机器上重装整个系统。我们只需要更新商业逻辑组件就可以了。
应用程序开发人员可以并行,独立的开发单独的层。


代码
这个组件有3层,第一个层或者称为GUI层用form实现,叫做FrmGUI。第二层或者称为商业逻辑层,叫做BOCustomer,是Bussniess Object Customer的缩写。最后是第三层或者称为数据层,叫做DACustomer,是Data Access Customer的缩写。为了方便,我把三个层编译到一个项目中。
用户接口层
下面是用户接口成的一段代码,我只选取了调用商业逻辑层的一部分代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;

namespace _3tierarchitecture
{
    class Class1
    {

        BOCustomer cus;

        //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 description for BOCustomer.
    ///
    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();

        }

        ///
        /// Property FirstName (String)
        ///
        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());
                }

            }

        }

        ///
        /// Property LastName (String)
        ///

        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 ...");

                }

            }

        }

        ///

        /// Property Customer ID (String)

        ///

        public String cusID
        {

            get
            {

                return this.cusId;

            }

            set
            {

                this.cusId = value;

                if (this.cusID == "")
                {

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

                }

            }

        }

        ///

        /// Property Address (String)

        ///

        public String Address
        {

            get
            {

                return this.address;

            }

            set
            {

                this.address = value;

                if (this.Address == "")
                {

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

                }

            }

        }

        ///

        /// Property Telephone (String)

        ///

        public String Tel
        {
            get
            {
                return this.tel;
            }

            set
            {
                this.tel = value;
                if (this.Tel == "")
                {
                    throw new Exception("Please provide Tel ...");
                }
            }
        }

        ///

        /// Function Add new customer. Calls

        /// the function in Data layer.

        ///

        public void Add()
        {

            cusData.Add(this);

        }

        ///
        /// Function Update customer details.
        /// Calls the function in Data layer.
        ///
        public void Update()
        {
            cusData.Update(this);
        }

        ///
        /// 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.
        ///
        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 description for DACustomer.

    ///

    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;

        }

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程通过实际项目融入常用开发技术架构,讲授风格独特,提供详细上课日志及答疑,赠送配套的项目架构源码注释详细清晰且表达通俗,均能直接在实际项目应用,正真的物超所值,价格实惠任务作业:综合运用《C#/.Net企业级系统架构设计实战精讲教程》课程所学知识技能设计一个学生成绩管理系统的架构。要求:1.系统基于MVC的三层架构,各层单独建不同的解决方案文件夹。2.采用Model First开发方式,设计架构时只需要设计学生表(TbStudent)和课程表(TbCourse)。学生表必须有的字段是ID、stuName、age;课程表必须有的字段是ID、courseName、content。3.数据访问层采用Entity Framework或NHibernate来实现,必须封装对上述表的增删改查方法。4.必须依赖接口编程,也就是必须要有数据访问层的接口层、业务逻辑层的接口层等接口层。层层之间必须减少依赖,可以通过简单工厂或抽象工厂。5.至少采用简单工厂、抽象工厂、Spring.Net等技术的2种来减少层与层之间的依赖等。6.封装出DbSession类,让它拥有所有Dal层实例和SaveChanges方法。7.设计出数据访问层及业务逻辑层主要类的T4模板,以便实体增加时自动生成相应的类。8.表现层要设计相关的控制器和视图来验证设计的系统架构代码的正确性,必须含有验证增删改查的方法。9.开发平台一定要是Visual Studio平台,采用C#开发语言,数据库为SQL Server。10.提交整个系统架构的源文件及生成的数据库文件。(注意: 作业需写在CSDN博客,请把作业链接贴在评论区,老师会定期逐个批改~~)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值