PDA

View Full Version : مقدار بازگشتی از لایه BLL به لایه UI در برنامه نویسی چند لایه



ahmad156
پنج شنبه 25 اسفند 1390, 11:14 صبح
دوستان عزیز توی لایه BLL مقداری که به لایه UI برمیگردونیم BO هست.اگر من بخوام آرایه ای از BO رو به عنوان DataSource یه GridView بگیریم چه جوری باید انجام بدم؟:متفکر:

aminghaderi
جمعه 26 اسفند 1390, 01:43 صبح
در برنامه نویسی لایه ای شما مالیکت لایه خود یا مجموعه کلاس های خود هستید و این یعنی یه مفهوم روتین و یا دات نتی نیست که بقیه هم اطلاعات داشته باشند.
الان چطوری می شه فهمید لایه BLL شما چطوری طراحی شده و چه پارامترهایی رو دریافت و چگونه با پارامتر ها برخورد می کنه.
حرفم اینکه این مسائل را باید خودتون و یا گروهتون باید مورد بررسی و خطا یابی کنید ، چون عام نیست ، لایه شخصی شماست.

امیدوارم منظورم رو درست رسانده باشم.
موفق باشی.

ahmad156
جمعه 26 اسفند 1390, 12:21 عصر
دوست عزیز
من گروهی کار نمیکنم.حالا تو این مورد خاص که من گفتم چه جوری میتونم آرایه ای از BO رو به عنوان DataSource یه گرید لحاظ کنم؟

clover
جمعه 26 اسفند 1390, 13:33 عصر
خیلی ساده هست، کافیه متد مورد نظر شما یه لیست از Business Entity ها رو برگردونه:

public List<BusinessEntity> GetList()
{}

برای راحتی بیشتر می تونید یه کلاس (موجودیت) مختص این کار ایجاد کنید:

public class BusinessEntityList : List<BusinessEntity>
{}

public BusinessEntityList GetList()
{}

موفق باشید

ahmad156
جمعه 26 اسفند 1390, 13:39 عصر
دوست عزیز میشه با یه مثال ساده بگین.متوجه نشدم:افسرده:

clover
جمعه 26 اسفند 1390, 14:03 عصر
دوست عزیز میشه با یه مثال ساده بگین.متوجه نشدم
لطف کنید کدی رو که برای حالت تکی استفاده کردید (کدهای لایه ی Business Logic به همراه کنترل های داده ای مورد استفاده ) قرار بدید تا روی همون توضیح بدم

ahmad156
جمعه 26 اسفند 1390, 14:16 عصر
این کد لایه DAL
public DataTable SelectPerson(int id)
{
string query = "call test(@id)";
OdbcParameter[] param = new OdbcParameter[1];
param[0] = new OdbcParameter("@id", id);
return DBInterface.RunQuery(query, param);
}
این هم کد لایه BLL

public PersonBO SelectPerson(int id)
{
PersonBO person = new PersonBO();
DataTable dt = new DataTable();
dt = personDAL.SelectPerson(id);
person.ID = Int32.Parse(dt.Rows[0]["id"].ToString());
person.Name = dt.Rows[0]["name"].ToString();
person.Famiy = dt.Rows[0]["family"].ToString();
person.Phone = dt.Rows[0]["phone"].ToString();
return person;
}

clover
جمعه 26 اسفند 1390, 14:44 عصر
می تونید از این تابع در لایه ی BL استفاده کنید:

public List<PersonBO> SelectList()
{
List<PersonBO> personList = new List<PersonBO>();
DataTable dt = new DataTable();
dt = personDAL.SelectList();


foreach (DataRow item in dt.Rows)
{
PersonBO person = new PersonBO();
person.ID = Int32.Parse(item["id"].ToString());
person.Name = item["name"].ToString();
person.Famiy = item["family"].ToString();
person.Phone = item["phone"].ToString();

personList.Add(person);
}

return personList;
}

البته دقت کنید که تبدیل دیتا رکورد ها به موجودیت ها رو باید در لایه ی دیتا انجام بدید (خروجی لایه ی دیتای شما باید موجودیت هایی مثل PersonBO و List<PersonBO> باشند و نه DataTable ها)

ahmad156
جمعه 26 اسفند 1390, 14:53 عصر
ممنون از جوابتون
یعنی خروجی لایه BO،DAL هاست .کاری که شما انجام دادین رو تو لایه DAL باید انجام داد؟پس تو لایه BLL باید چکار کرد؟:افسرده:

clover
جمعه 26 اسفند 1390, 15:33 عصر
کاری که شما انجام دادین رو تو لایه DAL باید انجام داد؟
بله

پس تو لایه BLL باید چکار کرد؟
توی پروژه های کوچیک عملا در لایه ی BL کاری انجام نمیشه، ولی بهتره وجود داشته باشه. اما این که در لایه ی BL چه کارهایی باید انجام داد رو با یک مثال توضیح میدم:
فرض کنید در همین سایت برنامه نویس قصد دارید اجازه ی حذف پست های نوشته شده توسط کاربران رو به اونها بدید. مسلما هر کاربر باید قادر باشه فقط پست های مربوط به خودش رو حذف کنه. خب کاری که شما می تونید انجام بدید اینه که دکمه ی "حذف" رو فقط برای پست هایی که مال کاربر هست نمایش بدید و در بقیه موارد اون رو مخفی کنید. این کار لازم هست اما کافی نیست، چرا؟ چون ممکنه کاربر به طریقی کد مربوط به خذف رو برای پستی که متعلق به خودش نیست فراخوانی کنه (جای توضیح داره)، از طرف دیگه باید این کار رو در تمام صفحاتی از سایت که عملیات حذف قابل انجام پیاده کنید(دقت کنید که در صفحات دیگه لزوما این کار توسط یه دکمه و به روش قبلی انجام نمیشه، ممکنه حذف گروهی باشه و یا به هر روش دیگه ای).
در واقع روش اصولی این هست که در متد حذف لایه ی BL این اعتبار سنجی انجام بگیره و در نهاییت نتیجه ی عملیات توسط یک خروجی (یک پیغام، کد وضعیت با ...) به لایه ی UI اطلاع داده بشه. در این صورت در هر جای برنامه که شما عملیات حذف داشته باشید می تونید از این متد با اطمینان استفاده کنید.

مثال های متعدد دیگه ای هم هست که در صورت لزوم می تونم توضیح بدم

موفق باشید

ahmad156
جمعه 26 اسفند 1390, 15:53 عصر
ممنون از جواب خوبتون
یعنی منظورتون اینه اعتبار سنجی تو این لایه رخ میده؟مثلا اگه تاریخ وارد شده اشتباه باشه این اعتبار سنجی رو تو لایه BL انجام میدیم؟
اگه مثال ذیگه ای باشه بهتر متوجه میشم

clover
جمعه 26 اسفند 1390, 16:12 عصر
یعنی منظورتون اینه اعتبار سنجی تو این لایه رخ میده؟
تقریبا، در واقع منطق برنامه ی شما در این بخش پیاده میشه، اگر بخواهیم سخت گیر باشیم باید اعتبار سنجی ها را هم در این لایه انجام بدیم و نه توسط کنترل های اعتبار سنجی، اما به جز اعتبار سنجی کلیه ی کدهایی که مربوط به منطق برنامه هستند (محاسبات، تبدیل ها، تصمیم گیری ها و ...) باید در این لایه صورت بگیرند.
مثال دیگه ای که میشه زد تبدیل تاریخ هست:
بنا به دلایلی بهتر هست که تاریخ به صورت میلادی در دیتابیس ذخیره بشه (و نه رشته تاریخ شمسی و یا انواع دیگه). اما در هنگام نمایش ما لازم داریم تاریخ رو به صورت شمسی نمایش بدیم. در این حالت بهتر هست یک Property در برای موجودیت خودتون تعریف کنید که واسط رو بین فیلد تاریخ اصلی و لایه ی UI بده. این فیلد می تونه در لایه ی BL مقدار دهی بشه و حتی در خود موجودیت.

ahmad156
جمعه 26 اسفند 1390, 16:17 عصر
ممنون دوست عزیز
فکر کنم تا حدودی متوجه شدم یه خرده کار میکنم ببینم چه قدر متوجه شدم.
اگه مثال های عملی هم بگین خیلی خوب میشه

EnKamran
جمعه 26 اسفند 1390, 23:53 عصر
ببینید دوست عزیز از کدهایی که نوشته بودید معلوم بود مفهوم 3 لایه بودن رو تا حدودی متوجه شدید، البته در اصل N-Layer هست که خوب ساده ترینش میشه 3 لایه شما توی این معماری میاید برامه رو به چند لایه تقسیم میکنید،اینها الگو(pattern) هستند که شما می تونید برای خودتون الگو درست کنید. اینکه بنده یا دوست عزیزمون clover صراحتا بگند که شما توی لایه دوم باید این کارها رو انجام بدید درست نیست چون این برنامه نویس هست که بنا به شرایط و بزرگی یا کوچکی برنامه تصمیم میگیره برنامه رو به چند لایه تقسیم کنه و هر لایه چه وظیفه ای داشته باشه. خوب تا اینجا مقدمه کوچکی بود.
ما گفتی که معماری 3 لایه معمولترین معماری هست که استفاده میشه، در این معماری لایه زیرین DAL هست که وظیفه کار با بانک رو داره، لایه BLL که لایه منطقی برنامه شما میشه و UI که ظاهر رو میسازه، با اومدن Entity Framework لایه DAL بسیار راحت و زیباتر شده، لایه DAL وظیفه این رو داره که مقادیری که قراره به DAL فرستاده بشه رو چک کنه(اعتبار سنجی) یا اعمال محاسباتی انجام بده و یا همونطور که دوستمون مثالی زدند تبدیل تاریخ ها رو انجام بده(این ها فقط مثال هستند) ببینید توی برنامه نویسی لایه ای قرار اینه که لایه زیری با لایه بالایی کهری نداشته باشه و فقط مقادیر دریافت کنه این لایه بالایی هست که به لایه زیری مقایر میفرسته، حالا شما فکر کنید که میخواهیم یک فرم رو توی بانک بریزیم از UI به BLL ارسال میشه و از BLL به DAL دیگه لایه DAL نمیاد چک کنه که آیا فیلد نام حتما نام وازد شده یا نه اشتباه وارد شده این لایه فقط وظیفه داره که مقادیر پاس داده شده بهش رو بریزه تو بانک، اینجاست که اهمیت لایه BLL معلوم میشه.
امید وارم تونسته باشم منظورم رو برسونم

mehdi-ghafari
شنبه 27 اسفند 1390, 03:27 صبح
واقعا مباحث برنامه نویسی چندلایه بحث بسیار کاربردی و شیرینی هست. ممنونم از دوستانی که راهنمایی میکنن.
چندتا سوال دارم.

لایه DAL وظیفه این رو داره که مقادیری که قراره به DAL فرستاده بشه رو چک کنهمنظورتون همون لایه BLL هست یا ...؟ و آیا اصلا DLL(Data Access Layer) درست هست یا DAL یا هردو یا هیچکدام؟

وی برنامه نویسی لایه ای قرار اینه که لایه زیری با لایه بالایی کهری نداشته باشه و فقط مقادیر دریافت کنه این لایه بالایی هست که به لایه زیری مقایر میفرستهخوب در اینصورت که برنامه ما یک طرفه میشه یا من هنوز اصل چندلایه رو نگرفتم؟؟! فرض کنید ما میخوایم یه محصول رو بریزیم تو دیتابیس و بعد از درج اطلاعاتش رو بگیری و نمایش بدیم. با این گفته شما ما داده ها را از UI به BLL و بعدش به DLL انتقال میدیم واسه Insert. خوب حالا واسه Select اطلاعات باید همین مسیر رو در جهت عکس برگردن دیگه DLL > BLL > UI. من کجای این مسئله رو درست متوجه نشدم ؟؟
و به عنوان سوال آخر : من خیلی دوست دارم برنامه نویسی چندلایه یاد بگیرم. لطفا بهم بگید از کجا و چطوری شروع کنم

بازم ممنون از شما

EnKamran
شنبه 27 اسفند 1390, 18:07 عصر
1. بله اشتباه تایپی بوده منظور همون BLL هست.

2 و 3 . شما دو پستی که بنده گذاشتم رو مطالعه کنید توی وبلاگم (http://sadin.ir) پست سوم که میشه BLL رو هم دارم آماده می کنم آخر امشب یا فرا آماده میشه چک کنید اگر سوالی بود بنده در خدمتم.

پ.ن : پست اول رو حتما مطالعه کنید، برنامه نویسی نیست اما کانسپت رو به شما می فهمونه و دلیل بوجود اومدن n-Layer رو. در کل پست اول رو حتما مطالعه کنید.

ahmad156
پنج شنبه 14 اردیبهشت 1391, 14:30 عصر
می تونید از این تابع در لایه ی BL استفاده کنید:

public List<PersonBO> SelectList()
{
List<PersonBO> personList = new List<PersonBO>();
DataTable dt = new DataTable();
dt = personDAL.SelectList();


foreach (DataRow item in dt.Rows)
{
PersonBO person = new PersonBO();
person.ID = Int32.Parse(item["id"].ToString());
person.Name = item["name"].ToString();
person.Famiy = item["family"].ToString();
person.Phone = item["phone"].ToString();

personList.Add(person);
}

return personList;
}


دوست عزیز اگر مقدار برگشتی من ترکیبی از چند Table باشه(join) به طوری که join من تو قالب یه object نباشه چه جوری میتونم این رو تبدیل به یه object کنم که بعد بتونم به عنوان dataSource یه GridView در نظر بگیرم

clover
پنج شنبه 14 اردیبهشت 1391, 19:09 عصر
دوست عزیز اگر مقدار برگشتی من ترکیبی از چند Table باشه(join) به طوری که join من تو قالب یه object نباشه چه جوری میتونم این رو تبدیل به یه object کنم که بعد بتونم به عنوان dataSource یه GridView در نظر بگیرم
خب یک راه حل می تونه این باشه که یه موجودیت جدید تعریف کنید که شامل چند موجودیت و یا ویژگی های چند موجودیت باشه یا حتی از چند موجودیت ارث برده باشه، کاملا بسته به پروژه خودتون

ahmad156
جمعه 15 اردیبهشت 1391, 18:31 عصر
یعنی اگر مقدار برگشتی من یه table باشه که تنها یه فیلد بیشتر از موجودیت موجود باشه یه موجودیت جدید براش تعریف کنم؟؟
راستی چه جوری میتونم List ای از یه موجودیت رو به عنوان یه DataSource یه GridView در نظر بگیرم؟

Saman Hashemi
شنبه 16 اردیبهشت 1391, 09:41 صبح
البته به نظر من استفاده از حلقه مورد خوبی نیست چون اگه تعداد رکورد زیاد باشه شاید عملیات زمانگیر باشه...!
شاید استفاده از LinQ اینجا مفید باشه...!
List<Employee> emp = new List<Employee>();
DataTable dt = ViewState["CurrentEmp"] as DataTable;
emp = (from DataRow row in dt.Rows
select new Employee
{
_FirstName = row["FirstName"].ToString(),
_LastName = row["Last_Name"].ToString()

}).ToList();
یه نکته دیگه اینه که مقدار بسیار زیادی از Validation میشه با خود Property انجام داد و نیازی نیست توی BLL انجام داد مگر در شرایط به خاصی...!
private int _JobID;
public int JobID
{
get { return _JobID; }
set
{
if (ValidateInt(value))
{
_JobID = value;
}
else
{
throw new Exception("شغل معتبر نیست");
}
}
}
پ.ن:ValidateInt برای چک کردن صحت value است...!

ahmad156
شنبه 16 اردیبهشت 1391, 10:05 صبح
دوست عزیز جوابتون رو متوجه شدم ولی ارتباطش رو با سوالم نه!
میشه بیشتر توضیح بدین

Saman Hashemi
شنبه 16 اردیبهشت 1391, 12:57 عصر
سوال اول متوجه نشدم یه فیلد از کجا اومده بالاخره متعلق به یه موجودیت هست حالا یا شما نیاز دارید که موجودیت جدید بسازید یا اینکه این فیلد به یک موجودیت اضافه کنید تصمیم گیری هم بسته به مورد متفاوت هست...!

GridView1.Datasource = emp;
GridView1.Databind();

پ.ن:در پست جواب سوال شما ندادم میخواستم به جواب یکی از دوستان پاسخ بدم و باید نقل قول کردم...!

ahmad156
یک شنبه 17 اردیبهشت 1391, 21:09 عصر
دوستان عزیز با مشکلی که من بر خوردم تا به حال کسی برخورد نکرده:ناراحت: