PDA

View Full Version : سوال: چگونگی پیاده سازی معماری سه لایه



Smn.Sdt
سه شنبه 18 مرداد 1390, 22:33 عصر
من با معماری سه لایه در حد تئوری تقریباً آشنا هستم. اما نمی دونم دقیقاً باید چه طور پیاده سازی بشه!
خب واسط گرافیکی که به طرز واضحی از بقیه لایه ها جداست اما نمی دونم چه طور باید لایه ی Data رو از لایه ی Business جدا کنم.
من الآن کوئری هام رو دقیقاً پشت فرم می نویسم. یعنی مثلاً اگه بخوام جستجو انجام بشه، کوئری و ایجاد DataAdapter و پر کردن DataTable رو در رویداد Click دکمه ی جستجو می نویسم، که می دونم اشتباهه، اما نمی دونم درستش چه طوریه؟

mas'oud
سه شنبه 18 مرداد 1390, 23:36 عصر
یک راه برای ایجاد لایه ی DAL اینه که یک کلاس به همین نام بساز و کانکشن و متدهای سلکت،دیلت،آپدیت و اینسرت رو مطابق با نوع برنامه ات توش بنویس.(آرگومان این متدها معمولا استرینگ هست و خروجیشون بستگی به نیاز شما میتونه void و string و ...) باشه.
مثلا اگه قراره عبارت داخل یک تکست باکس تو دیتابیس جستجو بشه یک شئ از DAL بساز و عبارت تکست باکس رو به عنوان آرگومان به متد جستجو که تو کلاس DAL نوشتی بفرست و خروجیشو بریز تو یه متغیر و ازش استفاده کن.
لبته این نوع سادش بود.

Smn.Sdt
چهارشنبه 19 مرداد 1390, 00:36 صبح
سپاس فراوان از پاسختون ...
بعد توی این روش که گفتید به نظرم بهتر باشه که برای هر کدوم از tableهای دیتابیسم یه کلاس DAL داشته باشم، نه؟ یا تقسیم بندی دیگه ای؟

mas'oud
چهارشنبه 19 مرداد 1390, 12:07 عصر
بستگی به نوع دیتابیستون داره!
مثلا اگه سه تا جدول دارید که یک فیلد مشترک دارن یک متد میتونه برای همشون کار کنه. البته منظور از فیلد مشترک id نیست چون معمولا فیلد id تو همه جدولها هست. مگر اینکه فیلدهای id با هم در ارتباط باشن.
به عنوان مثال من در برنامه خودم دیتابیسی داشتم که دارای 7 جدول بود. یکی از این جدولها جدولی بود برای پسورد برنامه و بقیه یک فیلد مشترک داشتن به نام title
حالا من میخواستم عبارتی رو توی این جدولهایی که فیلد مشترک داشتن جستجو کنم. فقط یک متد نوشتم(البته 2 بار این متد اورلود شده بود چون تعداد فیلدهای جداول یکسان نبود) و خروجی این متد ها استرینگ بود که باید استفاده میکردم.
قسمت مهم آرگومان متد بود که توضیح میدم:

چند تکست باکس و یک دکمه ذخیره و یک کمبو روی فرم بود که باید پس از زدن دکمه، عبارات داخل تکست باکس تو دیتابیس و جدول مربود ذخیره میشد.کمبو هم جدول رو مشخص میکرد.

برای هریک از گزینه های کمبو از متدم استفاده کردم ولی با آرگومانهای مختلف:



DAL dalObj = new DAL();
switch (cmbCat.SelectedIndex.ToString())
{
case "0":
{
string result = dalObj.CheckExist("title","[web]",txt1.Text);
if (result == txt1.Text)
{
Error2();
}
else
{
dalObj.SetCommand4("[web]", txt1.Text, txt2.Text, txt3.Text, txt4.Text);
Message();
}
}
break;

متد CheckExist هم چک میکرد که آیا رکوردی با عنوان مورد نظر وجود داره یا نه.(اینم توی DAL نوشتم)

میبینی که به متد SetCommand4 پنج آرگومان دادم که یکیش نام جدول رو پیدا میکنه و دیگر آرگومانها مقادیر تکستها رو به دستور سلک میده، اینم متد که تو لایه ی DAL نوشتم:


public string CheckExist(string field, string table, string search)
{
OleDbConnection con = f.con;
string checkexist = "SELECT " + field + " FROM " + table + " WHERE " + field + " LIKE '" + search + "'";
string result = "";
OleDbCommand cmd = new OleDbCommand(checkexist, con);
con.Open();
OleDbDataReader dr = cmd.ExecuteReader();
if (dr.Read())
result = dr[field].ToString();
else
result = "";
con.Close();

return result;
}

و

public void SetCommand4(string table, string set1,string set2,string set3,string set4)
{
OleDbConnection con = f.con;
string q = "INSERT INTO " + table + "(title,username,pass,url) VALUES(?,?,?,?)";
OleDbCommand cmd = new OleDbCommand(q, con);
cmd.Parameters.AddWithValue("@title", set1);
cmd.Parameters.AddWithValue("@username", set2);
cmd.Parameters.AddWithValue("@pass", set3);
cmd.Parameters.AddWithValue("@url", set4);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}


ببین من یک متد با دو بار اورلود شدن نوشتم و به تعداد جدولها ازش استفاده کردم. درصورتی که اگر مثل شما کد مینوشتم نزدیک به 100 خط به کدهای برنامه ام اضافه میشد.البته متد SetConnection هم اونجا نوشتم.

Smn.Sdt
چهارشنبه 19 مرداد 1390, 16:48 عصر
بسیار بسیار تشکر، خیلی خوب توضیح دادید :)
فقط یه سوال دیگه:
گاهی اوقات نتیجه ی جستجو یه table هست که مثلاً میخوایم توی یه DataGridView نمایشش بدیم. در این مواقع خروجی تابعی که توی DAL نوشتیم باید DataTable باشه؟ حجم زیاد خروجی تابع، مشکلی ایجاد نمیکنه؟ یا این که باید از روش دیگه ای استفاده کرد؟ مثلاً شیء DataGridView رو به عنوان آرگومان تابع پاس بدیم که توی تابعی که توی DAL نوشته شده پر شه؟ کدوم روش بهتره؟

mas'oud
چهارشنبه 19 مرداد 1390, 20:06 عصر
اصولا هر آبجکتی و یا نوع داده ای را به عنوان خروجی و آرگومان میشود به متد داد.
من امتحان نکردم که خروجی یا آرگومان میتونه دیتاتیبل باشه یا نه ولی حدس قوی دارم که میشه.
در این مواقع دستورات پر کردن دیتاتیبل رو هم باید توی DAL بنویسی.

به حجم و این چیزا هم ربط نداره چون بالاخره باید دیتاگریدتو پر کنی دیگه!!
البته نمیدونم چرا از بایند کردن استفاده نکردی؟؟؟؟

شما باید دنبال بهترین راه حل باشی چون پروژه شما میتونه نکاتی داشته باشه (و حتما داره) که سایرین ازش بیخبرن.
راه حل کلی برای مساله برنامه نویسی اینه:

سوال رو بگیر
خوب بخون
روش تفکر کن
تمامی راه حلهایی که به ذهنت میرسه انجام بده و یه نسخشو داشته باش
باز هم با تفکر و تحلیل خودت بهترین راه حل رو انتخاب کن. بهترین راه حل میتونه گزینه های زیر رو شامل بشه:
1.سرعت
2.کوتاه بودن کد
3.جامع بودن کد(تا جایی که ممکنه ازش استفاده بشه)
4.ایمن بودن کد

یه نکته هم یادم رفته بود بگم : لایه ی UI بیشتر توی وب اپلیکیشن نمود پیدا میکنه چون اونجا CSS داریم.