PDA

View Full Version : سوال: پیاده سازی صحیح برنامه به صورت سه لایه



csharpcollegian
دوشنبه 17 اسفند 1394, 08:34 صبح
سلام وقت به خیر
دوستان من یک برنامه به صورت سه لایه نوشتم که یک قسمتش وظیفه انتشار و ثبت بن خرید برای کارمندان شرکت رو بر عهده داره
ثبت اطلاعات بن خرید به این صورت انجام میشه که اطلاعات در لایه نمایش (Presentation Layer) گرفته میشه و به لایه منطق تجاری (Business Logic Layer) ارسال میشه :

private void button1_Click(object sender, EventArgs e)
{
BonClass Obj = new BonClass();
Obj.PersonnelID = textBox1.Text;
Obj.Description = textBox2.Text;
.
.
.
Obj.Insert();
}
بعد در لایه منطق تجاری اطلاعات توسط لایه دسترسی به داده (Data Access Layer) در دیتابیس ثبت میشه :

class BonClass
{
DataAccessLayer DAL = new DataAccessLayer();
.
.
.
public void Insert()
{
SqlParameter personnelIDParam = new SqlParameter("@PersonnelID", this.PersonnelID);
SqlParameter descriptionParam = new SqlParameter("@Description", this.Description);
.
.
.
DAL.ExecuteCommand("procBonInsert", CommandType.StoredProcedure, personnelIDParam, descriptionParam, ...);
}
.
.
.
}
برنامه باید قبل از ثبت بن خرید چک کنه که قبلا برای این کارمند بن خرید دیگه ای ثبت نشده باشه بعدش بن جدید رو ثبت کنه (هر کارمند فقط حق داشتن یک بن خرید در ماه رو داره)
من همیشه این جور شرط ها رو داخل لایه منطق تجاری و همون متد Insert پیاده سازی می کنم که زمانی که متد Insert در لایه نمایش صدا زده شد، تمامی شروط به صورت اتوماتیک چک بشن بعدش عمل Insert انجام بشه :

class BonClass
{
DataAccessLayer DAL = new DataAccessLayer();
.
.
.
public void Insert()
{
Checking Conditions //بررسی اینکه آیا قبلا بن خریدی برای کارمند ثبت شده یا نه
.
.
.
if(Conditions true)
{
SqlParameter personnelIDParam = new SqlParameter("@PersonnelID", this.PersonnelID);
SqlParameter descriptionParam = new SqlParameter("@Description", this.Description);
.
.
.
DAL.ExecuteCommand("procBonInsert", CommandType.StoredProcedure, personnelIDParam, descriptionParam, ...);
}
}
.
.
.
}
دلیلم واسه این کار اینه که اینجوری منطق اصلی برنامم در کلاس هام (لایه منطق تجاری) پیاده سازی میشه و دیگه در لایه نمایش درگیر مسائلی که مربوط به منطق برنامه هست نمیشم و فقط اعتبار سنجی انجام میدم
حالا سوالم از دوستان و اساتید محترم اینه که آیا این روشی که من به کار بردم(بررسی شروط در همان لایه منطق تجاری و متد Insert)، معماری سه لایه رو به صورت اصولی و صحیح پیاده می کنه و منطبق بر مفاهیم معماری سه لایه هست یا نه ؟
چون یکی از دوستان میگفت باید این شرط رو در همان لایه نمایش چک کنی، چون بررسی این شرط هم یه جور اعتبار سنجیه !
ولی از نظر من اینجوری لایه نمایش هم درگیر منطق برنامه میشه که درست نیست...!
دوستان ممنون میشم نظراتتون رو مطرح کنید

محمد آشتیانی
دوشنبه 17 اسفند 1394, 10:59 صبح
سلام
حدودا کاری که کردید درسته ، چک کردن شروط در لایه Business باید انجام بشه ، و UI عملا نباید درگیر چک کردن مقادیر و یا پر یا خالی بودن فیلدها باشه ، تنها کاری که در UI انجام می دید پر کردن یک آبجکت و ارسال اون به یک متد در لایه Business هست ، در لایه Business هم نباید کد دسترسی به داده و نظیر اینها رو داشته باشید.
به طور خلاصه شما در لایه UI و لایه Data هیچ بیزینسی (مثل چک کردن شروط ، اعتبار سنجی و ...) نباید داشته باشید.
یعنی حتی مقدار دهی sqlParameter هم در لایه Data باید انجام بشه ، این معنیش اینه که در صورتی که اعتبار سنجی شما موفقیت آمیز بود ، باید داده هاتون رو در قالب یک Business Object به لایه Data ارسال کنید و عملیات مرتبط رو (CRUD) انجام بدید و اگر هم در اعتبار سنجی خطایی داشتید باید یک پیغام مناسب رو به لایه UI بفرستید.




موفق باشید.

csharpcollegian
دوشنبه 17 اسفند 1394, 13:53 عصر
جناب آشتیانی ممنون بابت وقتی که گذاشتین یک سوال داشتم

یعنی حتی مقدار دهی sqlParameter هم در لایه Data باید انجام بشه ، این معنیش اینه که در صورتی که اعتبار سنجی شما موفقیت آمیز بود ، باید داده هاتون رو در قالب یک Business Object به لایه Data ارسال کنید و عملیات مرتبط رو (CRUD) انجام بدید و اگر هم در اعتبار سنجی خطایی داشتید باید یک پیغام مناسب رو به لایه UI بفرستید.
من اصلا به این مساله دقت نکرده بودم که خود sqlParameter هم عنصری از لایه Data Accessمحسوب میشه و استفاده از اون در لایه Business اشتباهه...
به نظرتون اگر از یک کلاس شبیه این استفاده کنم و اطلاعات پارامتر رو به لایه ی داده بفرستم و در لایه داده، sqlParameter رو با استفاده از این اطلاعات بسازم و درج کنم ایده ی خوبیه ؟
نظر شما چیه ؟

public class ParameterInformation
{
public string parameterName;
public string parameterValue;
public SqlDbType parameterType;
public ParameterDirection parameterDirection;

public ParameterInformation(string theParameterName, string theParameterValue, SqlDbType theParameterType, ParameterDirection theParameterDirection)
{
parameterName = theParameterName;
parameterValue = theParameterValue;
parameterDirection = theParameterDirection;
parameterType = theParameterType;
}
}

ali_md110
دوشنبه 17 اسفند 1394, 14:42 عصر
سازنده ها در یک کلاس معمولا هزینه بر هستند سعی کنید بصورت تزریق وابستگی و از یک کامپوننت ioc مثل StructureMap استفاده کنید
سعی کنید ازسال پارامتر بصورت یک آرایه یا یک دیتاتیبل باشه بجای theParameterValue
یعنی تمام داده هاتون از سمت UI درون یک دیتاتیبل بریزید و اون رو پاس بدید به لایه پایین تر و اونجا عملیات جک کردن و ولیدیشن روی دیتاتیبل انجام بدید سپس بفرستید به لایه پایین تر برای درج یا هر عملیات CRUD

csharpcollegian
دوشنبه 17 اسفند 1394, 14:52 عصر
سازنده ها در یک کلاس معمولا هزینه بر هستند سعی کنید بصورت تزریق وابستگی و از یک کامپوننت ioc مثل StructureMap استفاده کنید
سعی کنید ازسال پارامتر بصورت یک آرایه یا یک دیتاتیبل باشه بجای theParameterValue
یعنی تمام داده هاتون از سمت UI درون یک دیتاتیبل بریزید و اون رو پاس بدید به لایه پایین تر و اونجا عملیات جک کردن و ولیدیشن روی دیتاتیبل انجام بدید سپس بفرستید به لایه پایین تر برای درج یا هر عملیات CRUD
اگر ممکنه یه مثال خیلی کوچیک بزنید لطفا

ali_md110
دوشنبه 17 اسفند 1394, 16:26 عصر
http://barnamenevis.org/showthread.php?499049 (http://barnamenevis.org/showthread.php?499049-%D8%A7%D8%B1%D9%88%D8%B1-%D8%AF%D8%B1-%DA%A9%D8%A7%D9%86%DA%A9%D8%B4%D9%86-%D8%A7%D8%B3%D8%AA%D8%B1%DB%8C%D9%86%DA%AF-%D8%A8%D9%87-%D8%B1%D9%88%D8%B4-%D9%85%D8%AF%D9%84-%D8%B3%D9%87-%D9%84%D8%A7%DB%8C%D9%87&p=2230130#post2230130)

csharpcollegian
دوشنبه 17 اسفند 1394, 17:06 عصر
http://barnamenevis.org/showthread.php?499049 (http://barnamenevis.org/showthread.php?499049-%D8%A7%D8%B1%D9%88%D8%B1-%D8%AF%D8%B1-%DA%A9%D8%A7%D9%86%DA%A9%D8%B4%D9%86-%D8%A7%D8%B3%D8%AA%D8%B1%DB%8C%D9%86%DA%AF-%D8%A8%D9%87-%D8%B1%D9%88%D8%B4-%D9%85%D8%AF%D9%84-%D8%B3%D9%87-%D9%84%D8%A7%DB%8C%D9%87&p=2230130#post2230130)

علی آقا من کدتون رو بررسی کردم و کل اطلاعاتم رفت رو هوا !
من تا به امروز فکر می کردم واسه لایه ی DAL باید یک کلاس واحد و کامل نوشت (فقط یک کلاس) و برای تمام کلاس های لایه BLL از اون استفاده کرد !
خود من هم تا به امروز همین کار رو می کردم، یک کلاس واحد برای لایه DAL مینوشتم و بعد در لایه BLL همه کلاس ها ازش استفاده می کردن !
ولی با توجه به کد شما اگر درست متوجه شده باشم باید به ازای هر کلاس در BLL یک کلاس مخصوص در DAL طراحی بشه !
ممنون میشم یه خورده توضیح بدید

csharpcollegian
دوشنبه 17 اسفند 1394, 17:49 عصر
جناب آشتیانی ممنون بابت وقتی که گذاشتین یک سوال داشتم

من اصلا به این مساله دقت نکرده بودم که خود sqlParameter هم عنصری از لایه Data Accessمحسوب میشه و استفاده از اون در لایه Business اشتباهه...
به نظرتون اگر از یک کلاس شبیه این استفاده کنم و اطلاعات پارامتر رو به لایه ی داده بفرستم و در لایه داده، sqlParameter رو با استفاده از این اطلاعات بسازم و درج کنم ایده ی خوبیه ؟
نظر شما چیه ؟

public class ParameterInformation
{
public string parameterName;
public string parameterValue;
public SqlDbType parameterType;
public ParameterDirection parameterDirection;

public ParameterInformation(string theParameterName, string theParameterValue, SqlDbType theParameterType, ParameterDirection theParameterDirection)
{
parameterName = theParameterName;
parameterValue = theParameterValue;
parameterDirection = theParameterDirection;
parameterType = theParameterType;
}
}


این روش جواب نمیده، نمیشه از بیشتر امکانات Stored Procedure ها استفاده کرد...

ali_md110
دوشنبه 17 اسفند 1394, 20:12 عصر
ببینید دوست من
منظور از لایه بندی اینه که قسمتهای برنامه به پروژه های متفاوت و کتابخانه های مخصوصی تقسیم بندی بشه
و برنامه اصلی که همون UI هست از این کتابخانه ها رفرنس بگیره و استفاده بکنه
معمولا روال برنامه نویسی 3 لایه اینه به ازای هر موجودیت یک کلاس Dal و یک Bll مینویسند مثلا اگر یک جدول Product دارید یک کلاس بنام DAL_Product بنویسید و این کلاس فقظ وظیفه عملیات CRUD این جدول رو داشته باشه و همچنین کلاس BLL_product
بعضی وقتها شما میتونید اون موجودیتهایی که بهم مرتبط هستند رو توی یک کلاس DAL واحد قرار بدید مثلا ProdcutGroup و Product و عملیات مربوط به این دو جدول توی یک کلاس قرار بدید

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

csharpcollegian
سه شنبه 18 اسفند 1394, 06:42 صبح
ببینید دوست من
منظور از لایه بندی اینه که قسمتهای برنامه به پروژه های متفاوت و کتابخانه های مخصوصی تقسیم بندی بشه
و برنامه اصلی که همون UI هست از این کتابخانه ها رفرنس بگیره و استفاده بکنه
معمولا روال برنامه نویسی 3 لایه اینه به ازای هر موجودیت یک کلاس Dal و یک Bll مینویسند مثلا اگر یک جدول Product دارید یک کلاس بنام DAL_Product بنویسید و این کلاس فقظ وظیفه عملیات CRUD این جدول رو داشته باشه و همچنین کلاس BLL_product
بعضی وقتها شما میتونید اون موجودیتهایی که بهم مرتبط هستند رو توی یک کلاس DAL واحد قرار بدید مثلا ProdcutGroup و Product و عملیات مربوط به این دو جدول توی یک کلاس قرار بدید

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

اینجوری حجم کدها در لایه ی بیزینس خیلی کم و در لایه ی داده خیلی زیاد میشه که !
با تعویض دیتابیس حجم کدهایی که باید تغییر کنن هم میره بالا علی آقا درسته ؟
کدی که من نوشتم کاملا اشتباهه ؟
راهی برای تصحیح اون وجود نداره ؟ طوری که بشه یکتاییش در برنامه حفظ بشه ؟

setar20
چهارشنبه 10 آبان 1396, 10:15 صبح
دوستان خواهشااگه کسی عملی برنامه سه لایه نوشته جواب بده
وقتی میگیم یکی از مزایای برنامه نویسی سه لایه این هست که کاربر نمیتونه شخصا به لایه da دسترسی پیدا کنه
خب در برنامه نویسی به روش ساده هم کاربر نمیتونه این کارو انجام بده.. مگه میشه؟ لطفا یکی شرح بده با مثال
و سوال دوم اینکه در برنامه نویس سه لایه یه حسن دیگه لوکیشن ترنس پرنسی هست یعنی کاربر نمیفهمه داده ها از کجا به دستش میرسه دوباره بنظرم در برنامه نویسی ساده هم کاربر اینو نمیفهمه فرقش کجاست دقیقا؟لطفا با مثال توضیح بدین

ali_md110
چهارشنبه 10 آبان 1396, 12:30 عصر
این عبارت رو از کجا شنیدید؟
وقتی میگیم یکی از مزایای برنامه نویسی سه لایه این هست که کاربر نمیتونه شخصا به لایه da دسترسی پیدا کنه
بعدش منظور از کاربر چه کسانی هستند؟
منظور از کاربر , لایه UI برنامه یا پروژه هست نه کابر نهایی استغاده کننده از اپلیکیشن شما

ببینید دوست من
تمام برنامه های دات نتی یک یا چند لایه در نهایت بعد از کامپایل به یک یا چند فایل اسمبلی یا اجرایی تبدیل میشن و این لایه ها اطلاعات رو بین هم پاسگاری میکنن

setar20
چهارشنبه 10 آبان 1396, 13:47 عصر
این عبارت رو از کجا شنیدید؟
وقتی میگیم یکی از مزایای برنامه نویسی سه لایه این هست که کاربر نمیتونه شخصا به لایه da دسترسی پیدا کنه
بعدش منظور از کاربر چه کسانی هستند؟
منظور از کاربر , لایه UI برنامه یا پروژه هست نه کابر نهایی استغاده کننده از اپلیکیشن شما

ببینید دوست من
تمام برنامه های دات نتی یک یا چند لایه در نهایت بعد از کامپایل به یک یا چند فایل اسمبلی یا اجرایی تبدیل میشن و این لایه ها اطلاعات رو بین هم پاسگاری میکنن
ممنون از پاسختون.ببخشید من این اواخر اونقدر مطلب خوندم که از دستم در رفته درستش این بود:کاربر به صورت مستقیم با بانک اطلاعاتی و پردازش اصلی برنامه ارتباطی ندارد.
درسته اگه حساب کنیم کاربر یعنی اینترفیس جواب سوال اولمو گرفتم. ارتباطشون فقط از چه طریقی هست؟ من دیدم بعضی جاها بحث entity اورده و بعضی جاها خبری نیست
اصلا همین entityیه کلاس از نوع پروژست چوریه برنامه اونوقت 4 لایه میشه؟!!!؟

setar20
چهارشنبه 10 آبان 1396, 14:29 عصر
این عبارت رو از کجا شنیدید؟
وقتی میگیم یکی از مزایای برنامه نویسی سه لایه این هست که کاربر نمیتونه شخصا به لایه da دسترسی پیدا کنه
بعدش منظور از کاربر چه کسانی هستند؟
منظور از کاربر , لایه UI برنامه یا پروژه هست نه کابر نهایی استغاده کننده از اپلیکیشن شما

ببینید دوست من
تمام برنامه های دات نتی یک یا چند لایه در نهایت بعد از کامپایل به یک یا چند فایل اسمبلی یا اجرایی تبدیل میشن و این لایه ها اطلاعات رو بین هم پاسگاری میکنن
ببخشید شما اطلاعاتی هم راجع به راه های پاسکاری اطلاعات بین داده ها دارید؟ من از زبان اصی خوندم ولی کامل متوجه نشدم ..اگه ممکنه بصورت خلاصه یه توضیحی بدین..خیلی ممنون

ali_md110
چهارشنبه 10 آبان 1396, 16:20 عصر
وقتی حرف از پروژه ی 3 لایه میاد وسط اینطور نیست که حتمن 3 تا پروژه داشته باشه
یعنی DAL و BLL و UI ممکنه هرکدومشون به نوبه خود متشکل از چند پروژه باشه

این Entity یا موجودیت میتونه در یک پروژه جداگانه قرار بگیره و اسمشو مثلا میزاریم لایه مدل DataModel Layer واین لایه فقط دربرگیرنده مدلهای معادل جدول اطلاعاتی ماست و در کنار این پروژه یک پروژه دیگه میسازیم بنام DataLayer و این دوپروژه روی هم رفته لایه DAL تشکیل میدن
البته این بستگی به سلیقه شما داره و نوع توسعه دادن برنامتون
بستگی به گروه برنامه نویسی شما هم داره
که هرکس بر روی یک پروژه تمرکز بکنه و انجام بده
هدف چند لایه بیشتر همینه تا موارد دیگه

در مورد پاسگاری اطلاعات یعنی اطلاعات از لایه ui از کاربر گرفته میشه میره لایه bll درستی سنجی و موارد امنیتی روش انجام میشه و پاس داده میشه به لایه DataLayer و در دیتابیس درج میشه و دوباره میتونه مثلا یک لیست از اطلاعاتی که ثبت شد به لایه ui پاس داده بشه و به کاربر نشون داده بشه

در ضمن الگوی MVVM و MVC رو مطالعه بکنید