Jump to content

Welcome to [ iT ] Forums
Register now to gain access to all of our features. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more. If you already have an account, login here - otherwise create an account for free today!
MU Moi ra - MU Hai Phong

Hình ảnh

Xây dựng một chương trình C# theo mô hình 3 lớp

- - - - -

  • Please log in to reply
3 replies to this topic

#1
PhươngĐiệp2410

PhươngĐiệp2410

    Thạc sĩ CSTH

  • VIP
  • PipPipPipPipPip
  • 1917 Bài Viết:
Nguồn : CodeProject.com
Tác Giả : Rahman Mahmoodi
Dịch : PhươngĐiệp2410


Xây dựng Chương trình C# theo mô hình 3 lớp

Attached File  Three_tier_Architecture_src.zip   17.5KB   795 Lượi tải

I> Những Chỉ Dẫn

Trong mục này chúng ta sẽ thảo luận và xây dựng một chương trình C# thực thi theo mô hình 3 lớp và một người dùng ảo sử dụng cơ sở dữ liệu MS Access . Trong mục này Tôi đã thử thực thi những thành phần nhỏ có thể dùng lại (reusable) để bảo vệ người dùng trong việc xây dựng theo 3 lớp . Mục này sẽ nói cho ta biết làm thế nào để thêm (add) , cập nhập (update), và tìm kiếm chi tiết người dùng .

II> Nền tảng :

Để bắt đầu chúng ta sẽ thảo luận về 1 vấn đề nhỏ sơ bộ về lý thuyết của việc xây dựng mô hình 3 lớp . Tôi sẽ đi qua một cách vắn tắt để bạn biết cái gì gọi là mô hình 3 lớp và những thuận lợi khi bạn dùng nó .

Cái gì để xây dựng một mô hình 3 lớp :

Mô hình 3 lớp là kiến trúc kiểu client - server trong đó nó sử dụng giao diện người dùng , quá trình diễn biến , cất giữ và truy vập dữ liệu để người phát triển bảo vệ những modules (bộ phận tháo rời được) độc lập hoặc nhiều nền riêng rẽ . Về cơ bản một chương trình có 3 lớp thì từng lớp sẽ làm những nhiệm vụ sau :
+ Lớp 1 ==> Giới thiệu lớp , lớp GUI
+ Lớp 2 ==> Đối tượng của lớp này là các nhiệm vụ trong chương trình , những lớp nhiệm vụ mang tính logic .
+ Lớp 3 ==> Lớp truy cập dữ liệu .
Ở đây lớp có thể phát triển và tách riêng ra để kiểm tra .

Cái gì cần để chia lớp ra làm 3 lớp ? Việc chia giao diện người dùng từ nhiệm vụ mang tính logic và truy cập cơ sở dữ liệu có nhiều thuận lợi . Một vài thuận lợi ta có thê thấy phía dưới .
* Có thể dùng lại các lớp .Cho phép chúng ta có một module để thêm , cập nhập , xoá và tìm kiếm người dùng trong hệ thống . Nếu như những thành phần này đã được kiểm tra và phát triển thì chúng ta có thể dùng lại nó trong bất cứ project nào tương tự .
* Ta có thể thay đổi hệ thống một cách dễ dàng . Nếu ở đây các lớp của chúng ta có những thay đổi nhỏ thì chúng ta cũng không cần phải cài đặt lại chương trình của chúng ta trên máy của người dùng (Dạng như cập nhập phiên bản mới) . Nếu sự thay đổi đó trong khoảng từ 10 % đến 15% thì bạn chỉ cần cập nhập lại các lớp này .
* Có những hàm riêng rẻ trong server cho phép phát triển song song những lớp riêng rẻ bởi chuyên gia phần mềm .
* Cung cấp nhiều tài nguyên linh hoạt .

III> Sử dụng Code

Chương trình mà bạn tải ở trên có 3 lớp . Lớp thứ nhất hay còn gọi là FrmGUI , lớp thứ hai hoặc những nhiệm vụ logic sẽ được gọi tắt BOCustomer cho đối tượng Customer và cuối cùng lớp thứ ba hay còn gọi là lớp dữ liệu sẽ gọi tắt để truy cập dữ liệu của người dùng . Tôi có biên soạn tất cả lớp trong những project giống nhau để làm việc nhẹ nhàng hơn . Tôi bao gồm lại những mã nguồn dọc theo cơ sở dữ liệu Access , cái mà được sử dụng để kiểm tra trong project này bao gồm trong file zip .

Lớp Thứ Nhất (User Interface Tier)

Đây là một đoạn của code từ giao diện của người dùng . Tôi chỉ bao gồm những hàm được sử dụng để gọi lớp giữa (lớp thứ hai) .

Tôi sẽ giữ tham chiếu đến lớp thứ hai như BOCustomer.

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

Lớp Thứ Hai (Business Logic Layer)

Ở đây tôi sẽ bao gồm tất cả những đoạn code trong lớp này . Những thuộc tính cơ bản của nó là để định nghĩa cho đối tượng người dùng . Nhưng như tôi đã đề cập thì đây là những người dùng ảo và có khi phải cập nhập thêm vào khi sử dụng . Nó cũng có tất cả các phương thức bao gồm những việc như thêm , tìm kiếm , sửa chữa được sử dụng để bảo quản chi tiết người dùng .
Đây là lớp thứ hai (lớp giữa) sẽ thực thi những hành động giữa lớp thứ nhất và thứ ba . Nó giữ một tham chiếu đến lớp truy cập dữ liệu (lớp thứ ba ) chẳng hạn như cusData = new DACustomer() . Nó cũng tham chiếu đến namespace System.Data và đôi khi nó chả về chi tiết trong Form của Dataset đến lớp thứ nhất .
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;
			  }
		}
  }

Lớp Thứ Ba (Data Access Layer)

Đây là lớp dữ liệu có chi tiết về cơ sở dữ liệu MS Access . Tuy nhiên tất cả những chi tiết thì cũng rõ ràng và không ảnh hưởng đến lớp thứ hai . Module này sẽ tham chiếu đến lớp thứ hai như BOCustomer cus . Để có thể dễ dàng sử dụng bởi bất kì một cơ sở dữ liệu khác tôi đã tạo một vài hằng số bao gồm có tên cơ sở dữ liệu và tên vùng cần thay đổi như bảng chi tiết về người dùng . Đây là một module có thể dùng cho bất kì một cơ sở dữ liệu nào sau khi đã thay đổi .
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;
			
		}
	}
}

Bài viết này được chỉnh sửa bởi PhươngĐiệp2410: 25 May 2008 - 09:50 AM

http://winsocks.net/

Are You looking for a good socks 5 service? But you don't know where to buy?
Welcome to WinSocks.Net - Crazy Socks Service
Here we provide Fresh Socks 5 with fast speed , less blacklist, especially price is cheaper than others service.
More over, if you want to test our socks 5 before buying, don't be hesitate to contact our supporter through yahoo to receive Free Socks 5

#2
khanhpt

khanhpt

    Cao đẳng CSTH

  • Advance Member
  • PipPipPipPip
  • 682 Bài Viết:
Bài viết của bác rất hay và đầy đủ x(
Thủ thuật, mẹo vặt cho cuộc sống
http://www.mozilla.com/en-US/firefox/ Vừa nhanh hơn IE lại vừa "đề kháng" với các kiểu keylogger dính vào web :)
http://cuasotinhoc.vn/index.php?showtopic=154488

#3
Thien Huy

Thien Huy

    Căn bản tin học tốt

  • Advance Member
  • Pip
  • 90 Bài Viết:
đúng là bài tui đang kiếm!!
đang định học viết 3 lớp mà ko biết lợi ích của nó đâu hết!! :ac

giờ thì yên tâm đầu tư dzô nó rùi!!
Đời đổi thay khi ta biết thay đổi

#4
dollylamb

dollylamb

    Căn bản tin học tốt

  • Advance Member
  • Pip
  • 80 Bài Viết:
Tôi cho rằng cách tác giả thiết kế chương trình theo mô hình 3-tiers như bài dịch của bạn phuongdiep là không ổn. Vì sao? Không bàn đến lớp DataAccess. Với 2 lớp ở trên ta thấy ngay sự liên kết trong chương trình của tác giả khá là lỏng lẻo. Theo 1 logic thông thường thì khi tôi làm việc với 1 DataObject provider thì dữ liệu tôi mong muốn trả về phải là 1 dạng nào đó theo đúng tinh thần DO. Trong các pattern về lập trình nhiều lớp, việc trả về các đối tượng nằm ngoài phạm vi phục vụ của DO là 1 việc làm tồi. Có thể dễ thấy điều đó trong ví dụ của tác giả. Lớp view sau khi gọi phục vụ từ lớp BuinessLogic lại nhận dữ liệu trả về là 1 DataSet?? Tại sao làm việc với lớp nghiệp vụ dữ liệu trả về không phải là 1 application class object của lớp nghiệp vụ mà lại là 1 DataSet?? Theo tôi, mã trên của tác giả nên sửa 1 ít ở lớp Business và lớp View (User interface) như sau:

View:
Customer CustObj = new Customer();
Customers CustList = new Customers();

CustObj = CustList.Find(cusID);

txtField1.Text = CustObj.CustomerName.toString();
....
....

Business:
Viết lại 1 số thủ tục tương ứng.

Với cách làm thế này, ta đáp ứng đúng mong muốn của View là nhận về 1 đối tượng nghiệp vụ thực sự và đồng thời tuân thủ đúng tinh thần của mô hình lập trình nhiều lớp.

Mời mọi người tiếp tục thảo luận.




0 người đang đọc chủ đề này

0 thành viên, 0 khách, 0 thành viên ẩn



MU Moi ra - MU Phuc Sinh

Balloon vs. Thorns

MU Phuc Hung

Làm Việc Tài Nhà

Mu Da Nang

Tuyển Nhân Viên Bán Hàng

Tư vấn sức khỏe trực tuyến