تشریح لایه ها در معماری سه لایه

هر پروژه ای که در آن از تکنیک برنامه نویسی سه لایه استفاده می شود به سه بخش کلی(لایه) تقسیم می شود :

  • Presentation Layer : در این لایه ظاهر برنامه قرار می گیرد ، از طریق این لایه کاربران می توانند با برنامه ارتباط برقرار کنند و داده های خود را مشاهده یا وارد نمایند.
  • Business Logic Layer : منطق اصلی برنامه در این لایه قرار می گیرد . قوانین و کد های معتبر سازی ( Validation ) و دسترسی ( Authentication ) در این لایه قرار می گیرند .
  • Data Access Layer: همانطور که از اسمش می توان فهمید در این لایه کد های دسترسی به داده نوشته می شود . در این لایه می توانید از تکنولوژی های مختلف بانک اطلاعاتی همانند Entity Framework ، Linq to Sql ، Ado.net استفاده کنید .

قصد دارم که با 2 کلاس DALPersonel ( Data Access Layer ) و BLLPersonel ( Business Logic Layer ) و به کمک فرم نمایش داده ها برنامه نویسی سه لایه را جهت ورود داده ها برای جدول Personel پیاده سازی نماییم . ابتدا یک بانک اطلاعاتی با یک جدول با نام tablePersonels و سه فیلد به نام های Id ، FirstName ، LastName ایجاد می کنیم :

ThreeLayer-In-Csharp-23

سپس دو کلاس به نام های BLLPersonel و DALPersonel ایجاد می کنیم :

ThreeLayer-In-Csharp-24

بر روی کلاس DALPersonel دابل کلیک کرده و کد ها زیر را در آن قرار دهید (رشته اتصال بانک اطلاعاتی(خط 5) را مناسب با سیستم و مشخصات بانک اطلاعاتی خود تغییر دهید) :

 1: public DataTable SelectData()
 2: {
 3: 	string selectQuery = "SELECT * FROM tablePersonels;";            
 4: 	SqlCommand Command1 = new SqlCommand();
 5: 	SqlConnection Connection1 = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\DataBase.mdf;Integrated Security=True;Connect Timeout=30");
 6: 
 7: 	Command1.CommandText = selectQuery;            
 8: 	Command1.Connection = Connection1;
 9: 
10: 	SqlDataAdapter DataAdapter1 = new SqlDataAdapter(Command1);
11: 	
12: 	try
13: 	{             
14: 		DataTable result = new DataTable();
15: 		DataAdapter1.Fill(result);
16: 		return result;
17: 	}
18: 	catch (Exception ex)
19: 	{
20: 		MessageBox.Show(ex.Message);
21: 		return null;
22: 	}
23: 	finally
24: 	{
25: 		Command1.Connection.Close();
26: 	}
27: }

سپس بر روی کلاس BLLPersonel دابل کلیک کرده و کد زیر را در آن قرار دهید :

  1: public DataTable Select() {
  2: 	try
  3: 	{
  4: 		if (!System.IO.File.Exists("personel.txt"))
  5: 		{
  6: 			DALPersonel DALPersonel1 = new DALPersonel();
  7: 			DataTable result =  DALPersonel1.SelectData();
  8: 			return result;
  9: 		}
 10: 		else
 11: 		{
 12: 			return null;
 13: 		}
 14: 	}
 15: 	catch (Exception ex)
 16: 	{
 17: 		System.Windows.Forms.MessageBox.Show(ex.Message);
 18: 		return null;               
 19: 	}
 20: }

از آنجاییکه لایه BLL منطق برنامه را بر عهده دارد ، در این لایه بررسی می کنیم که اگر شروطی حاکم بود عمل اتصال به لایه Data Access انجام شود . مثلا در مثال بالا ابتدا بررسی می کنیم که آیا فایل personel.txt در مسیر پروژه قرار دارد یا خیر . اگر وجود نداشته باشد ارتباط با بانک برقرار می کنیم . این شرط فقط به عنوان مثال نوشته شده است و در برنامه های شما ممکن است شروط خاص خود را داشته باشید. بر روی فرم دابل کلیک کرده و کد زیر را در رویداد Load آن می نویسیم :

  1: BLLPersonel BllPersonel1 = new BLLPersonel();
  2: foreach (DataRow currentRow in BllPersonel1.Select().Rows)
  3: {
  4: 	MessageBox.Show(currentRow["FirstName"].ToString());
  5: }

در کد بالا از کلاس BLLPersonel شی ای را می سازیم . این کد باعث ارتباط لایه Presentation با Business Logic می شود . در شکل زیر نمای کلی ارتباط لایه های مذکور نشان داده شده است :
ThreeLayerNotComplete-csharp

مزایای کد نویسی به شکل بالا

در برنامه بالا کد ها به شیوه ی تمیز تر و بهتری نوشته شده اند . کد ها در هم پیچیده نیستند و منطق برنامه به بخش های جدا از هم تقسیم می شود . مزیت مهمتری که کد نویسی بالا دارد این است که ممکن است در برنامه ای از تکنولوژی قدیمی مثل Ado.net برای دسترسی به داده استفاده کرده باشیم و بعد از مدتی که تصمیم گرفتیم که از تکنولوژی جدیدتری مانند Entity Framework یا Linq to Sql برای دسترسی به داده استفاده کنیم اگر منطق برنامه مانند شکل بالا به قسمت های مناسبی تقسیم بندی شده باشد و لایه ی Data Access وجود داشته باشد به راحتی می توانیم فقط این لایه را دستکاری کنیم .

معایب کد نویسی به شکل بالا

در شکل بالا اگر به کد های لایه ی نمایش ( Presentation ) دقت کنید ، این لایه هیچگونه شناختی از فیلد ها و ستون های بانک اطلاعاتی ندارد و در زمان اجرا ساختار بانک را درک می کند . معمولا وظیفه حل این مشکل بر عهده لایه ی Business Logic هست به این صورت اگر این لایه ساختار بانک را بشناسد ، لایه ی Presentation نیز با توجه به ارتباطی که با این لایه دارد ساختار بانک را درک می کند . راه حلی که برای این مشکل وجود دارد این است که می توانیم یک کلاس اضافی به پروژه اضافه کنیم و ساختار بانک را در ان تعریف کنیم ، سپس این کلاس را در هر 3 لایه استفاده کنیم . به این ترتیب هر سه لایه از ساختار بانک اطلاعاتی باخبر می شوند. این لایه جدید Business Entity Layer نام دارد .

Business Entity Layer

در این لایه به ازای هر جدول موجود در بانک ، یک کلاس همنام با آن به همراه خصوصیاتی متناظر با فیلد های جدول ایجاد می کنیم ، پس از ایجاد لایه ی موجودیت ، این لایه به طور مشترک در بین تمامی لایه های استفاده می شود :
2015-06-26_9-39-20

به عنوان مثال در بانک اطلاعاتی شکل زیر یک جدول به نام tablePersonels وجود دارد . این جدول دارای فیلد هایی به نام Id ، FirstName ، LastName می باشد . برای تبدیل این جدول به یک کلاس Entity Layer شما باید یک کلاس هم نام به این جدول و خصوصیاتی همنام با فیلد های آن ایجاد کنید.

ThreeLayer-In-Csharp-25

در شکل زیر عمل Insert را با استفاده از معماری جدید می نویسیم :

ThreeLayerNotComplete-csharp-01

در مثال بالا کد ها نسبت به مثال قبلی شکل بهتر و قابل فهمتری دارند ولی بازهم مشکلاتی دارد . به عنوان مثال جداسازی کد ها می تواند به شکل بهتری انجام شود . مثلا هر لایه را می توان در یک Class Library قرار داد و با استفاده از Reference ها بین لایه ها ارتباط برقرار کرد . برای تقسیم بندی صحیح لایه های بهتر است هر لایه را در یک پروژه از نوع Class Library یا همان Dll ها قرار دهیم ( به جز لایه ی Presentation).

کتابخانه ی Data Access

در این لایه به ازای هر جدول وجود در بانک یک کلاس همنام با آن ایجاد می کنیم و در آن کد های دسترسی به جدول مانند چهار عمل اصلی را می نویسیم. خروجی کامپایل این پروژه از نوع Dll می باشد و باید به پروژه Business Logic آن را اضافه کنیم. این کار را برای این انجام می دهیم که بتوانیم به کد های این پروژه در لایه ی جدید(Business Logic) دسترسی داشته باشیم.

کتابخانه ی Business Logic

در این لایه به ازای هر کلاس موجود در کتابخانه ی Data Access Layer یک کلاس جهت مدیریت عملکرد متد ها و توابع کلاس های کتابخانه Data Access ایجاد می کنیم . این لایه فایل DLL خروجی حاصل از کتابخانه Data Access Layer را استفاده می کند . خروجی کامپایل این پروژه یک فایل Dll است که در لایه Presentation Layer استفاده خواهد شد . مثلا اگر در لایه ی Data Access یک کد ثبت نوشته باشیم باید در این پروژه یک متد همنام با آن ایجاد کنیم و شروطی را بررسی کنیم مثلا اگر مقادیر تمامی فیلد ها پر شده باشد عمل ثبت را انجام دهد .

کتابخانه ی Business Entity

در این لایه به ازای هر جدول موجود در بانک یک کلاس همنام با آن ، و به ازای هر ستون موجود یک خصوصیت همنام با آن ایجاد می کنیم .
خروجی کامپایل این پروژه یک فایل Dll بوده که در هر سه لایه به صورت مشترک استفاده می شود .