C#编程中的3层架构

来源:互联网 发布:没有网络连接 编辑:程序博客网 时间:2024/05/21 09:35

c#编程中实现3层架构
时间: 2011-4-24 10:27:20

  这篇文章讨论如何在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 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;

  }

  }


原创粉丝点击