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

简介:   这篇文章讨论如何在c#中实现3层架构,使用MS Access数据库存储数据。在此,我在3层架构中实现一个小型的可复用的组件保存客户数据。并提供添加,更新,查找客户数据的功能。  背景  首先,我介绍一些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 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;
}
}
}
目录
相关文章
|
1月前
|
架构师 测试技术 Linux
嵌入式软件架构中抽象层设计方法
嵌入式软件架构中抽象层设计方法
43 0
|
1月前
|
Linux
嵌入式软件实现应用层和硬件层分层管理
嵌入式软件实现应用层和硬件层分层管理
15 0
|
2月前
|
机器学习/深度学习 算法 文件存储
QuadraNet部署之星 | 从神经元重构到结构和整个模型的全面设计
QuadraNet部署之星 | 从神经元重构到结构和整个模型的全面设计
38 0
|
6月前
|
存储 监控 BI
|
11月前
|
存储 开发框架 前端开发
「技术架构」TOGAF建模之技术架构:网络计算硬件图
「技术架构」TOGAF建模之技术架构:网络计算硬件图
|
11月前
|
存储 开发框架 前端开发
「技术架构」TOGAF建模:网络计算硬件图
「技术架构」TOGAF建模:网络计算硬件图
|
11月前
|
机器学习/深度学习 计算机视觉 网络架构
即插即用系列 | 清华提出最新移动端高效网络架构 CloFormer: 注意力机制与卷积的完美融合!
即插即用系列 | 清华提出最新移动端高效网络架构 CloFormer: 注意力机制与卷积的完美融合!
666 0
|
存储 监控 Android开发
嵌入式软件组件经典架构与存储器分类
嵌入式软件组件经典架构与存储器分类
195 0
嵌入式软件组件经典架构与存储器分类
|
canal 存储 消息中间件
专车数据层架构进化往事
很多年前,读了子柳老师的《淘宝技术这十年》。这本书成为了我的架构启蒙书,书中的一句话像种子一样深埋在我的脑海里:"好的架构是进化来的,不是设计来的”。
|
机器学习/深度学习 存储 人工智能
如果将元宇宙逐层拆解,你会发现内核是“云”
如果将元宇宙逐层拆解,你会发现内核是“云”
107 0