背景
首先,我介绍一些3层架构的理论知识。简单说明:什么是3层架构?3层架构的优点是什么?
什么是3层架构?
3层架构是一种“客户端-服务器”架构,在此架构中用户接口,商业逻辑,数据保存以及数据访问被设计为独立的模块。主要有3个层面:
1.第一层(表现层,GUI层);
2.第二层(业务对象,业务逻辑层);
3.第三层(数据访问层)。这些层可以单独开发,单独测试。
为什么要把程序代码分为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 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;
- }
- }
- }