PDA

View Full Version : سوال: دقیقا کی باید از Exception Handling استفاده کنیم؟



Programmer 1
شنبه 03 فروردین 1392, 21:06 عصر
سلام دوستان،
اصولا و به لحاظ استاندارد دقیقا چه زمانی باید از Exception Handling استفاده کنیم؟
مثلا وقتی فایل مورد نیاز وجود نداشته باشه ممکنه از مدیریت استثنا استفاده کنیم؟ خب مگه نمی تونیم قبل از دسترسی به فایل، اول ببینیم هستش یا نه و این کار رو با مدیریت استثنا انجام ندیم؟
یا مثلا ورودی مورد نیاز برای تکست باکس سن طرف از نوع عددی است و انتظار مقدار عددی داریم ولی ممکنه کاربر مقداری رشته ای رو وارد کنه؟ اینجا نیز متونیم از مدیریت استثنا استفاده کنیم و یا خودمون مقدار ورودی رو کنترل کنیم، مثلا با اخطاری درخواست اطلاعات مناسب کنیم و یا اصلا اجازه وارد کردن بعضی کارکترها رو ندیم؟
در موقعیت های این چنینی که امکان استفاده از هر دو روش رو داریم از کدوم روش باید استفاده کنیم؟

اصلا موقعیتی وجود دارد که استثناها بتوانند مدیریت کنند و ما نتونیم؟ اگه آره لطفا مثال بزنید و با ذکر دلیل.

دقیقا چه زمانی شایسته است که از Exception Handling استفاده کنیم؟

علی متقی پور
شنبه 03 فروردین 1392, 22:24 عصر
سلام دوست عزیز
سوال، سوال خوبیه اما نه به سادگی ای که شما مطرح کردید
تو موادری که شما فرمودید اصلا بحث اکسپشن وجود نداره و بحث ولیدیتورهاست. اکسپشن بیشتر جایی مطرح میشه که کار دست ما نیستش. مثلا وقتی میخوای با دیتا بیس کار کنی دیگه برنامه نویس نمیدونه که آیا اصلا دیتا بیس ریسانسیو هست یا نه. یا کانکشن استرینگ درست ست شده یا نه. شاید سیستم طرف اینقد کند باشه که اپن کردن دیتا بیس طول بکشه و تایم اوت بشه. بهر حال برای بنده هم سواله که با توجه به هزینه ایکه که استفاده از try...catch داره چقد باید ازش استفاده کنیم. آیا هر جایی که ممکنه خطا رخ بده باید بذاریم یا نه جاهاییکه امکان خطا از یه درصدی بالاتره.
والا بلا همین ویندوز و خود VS خودشون ارور های هندل نشده دارن. چه برسه برنامه های ما :-)

plus
شنبه 03 فروردین 1392, 22:45 عصر
سناریوهای متفاوتی میشه مطرح کرد.یکی اینکه برای مثال شما متدی نوشتی که بر اساس یک عدد ورودی، محاسباتی رو انجام میده و یک عدد برمیگردونه.حالا در صورتی که ورودی مناسب نباشه، شما چی میخوای برگردونی ؟

private int DoSomeCalculation(int param1)
{
if (param1 == 0)
throw new ArgumentException("param1 cannot be zero.");

return ...;
}

یا سناروی دیگه اینکه، شما توی متدتون از کدی استفاده میکنی که خودش ممکنه Expception تولید کنه و نمیخواین در صورت رویدادن Exception، این Exception به لایه های بالاتر بره (میخواین هندل بشه)، مثلا با فایل کار میکنید:

private bool DoSomething(string data)
{
try
{
data = File.ReadAllText([some address]);
}
catch (Exception e)
{
return false;
}
return true;
}

سناریو های متفاوت دیگه ای هم هست...البته این رو در نظر داشته باشید که برای اکثر این سناریو ها، جایگزین هایی هم هست ولی شاید خیلی جاها استفاده از Exception مناسب تر باشه.

Programmer 1
شنبه 03 فروردین 1392, 23:13 عصر
ضمنا سوال دیگه ای هم دارم، به نظرتون هندل کردن استثنا بهتره کجا صورت بگیره؟
فرض کنید برنامه مون سه لایه است.
در لایه داده، متدهای ConnectToDatabase,RetriveData به ترتیب برای دریافت اطلاعات و اتصال به دیتابیس رو داریم.
در لایه نمایش دیتاگریدی داریم که با استفاده از متد FillDataGrid اطلاعات خاصی رو از دیتابیس می گیره و در دیتاگرید قرار میده.
متد FillDataGrid به ترتیب از RetriveData و این متد هم از ConnectToDatabase استفاده میکنه.

حالا اگر بخواهیم استثنای مرتبط با اتصال با دیتابیس رو مدیریت کنیم در کدوم یک از این متد ها این کار رو انجام بدیم یعنی کدهای کدوم یک از این متد ها رو بین try...catch قرار بدیم.

لازم به ذکره که هر چقدر به متدهای نزدیک به دیتابیس میرسیم درصد فراخوانی اونها هم در برنامه بیشتر میشه و به مسلما استفاده از مدیریت استثنا در این متدها میتونه کارایی برنامه رو افزایش بده.

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

Programmer 1
شنبه 03 فروردین 1392, 23:25 عصر
سناریوهای متفاوتی میشه مطرح کرد.یکی اینکه برای مثال شما متدی نوشتی که بر اساس یک عدد ورودی، محاسباتی رو انجام میده و یک عدد برمیگردونه.حالا در صورتی که ورودی مناسب نباشه، شما چی میخوای برگردونی ؟

private int DoSomeCalculation(int param1)
{
if (param1 == 0)
throw new ArgumentException("param1 cannot be zero.");

return ...;
}

یا سناروی دیگه اینکه، شما توی متدتون از کدی استفاده میکنی که خودش ممکنه Expception تولید کنه و نمیخواین در صورت رویدادن Exception، این Exception به لایه های بالاتر بره (میخواین هندل بشه)، مثلا با فایل کار میکنید:

private bool DoSomething(string data)
{
try
{
data = File.ReadAllText([some address]);
}
catch (Exception e)
{
return false;
}
return true;
}

سناریو های متفاوت دیگه ای هم هست...البته این رو در نظر داشته باشید که برای اکثر این سناریو ها، جایگزین هایی هم هست ولی شاید خیلی جاها استفاده از Exception مناسب تر باشه.

این که مسلمه برای سناریو های مختلف، جایگزین های مختلفی وجود داره! ولی سوال اصلی اینه که بهترین انتخاب کدومه؟

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

plus
شنبه 03 فروردین 1392, 23:58 عصر
در مورد مثالی که زدین ...بله Validation باعث میشه کاربر نتونه داده اشتباه وارد کنه ولی این موضوع، خودش میتونه پیچیدگی کار رو بالا ببره و گاهی هم موجب گذاشتن محدودیت زیاد واسه کاربر میشه و دست و پاشو میبنده...دوم اینکه شما داده رو درسته از کابر میگیرین و میتونین روی ورودی کاربر محدویت بگذارین، ولی این داده توی لایه های مختلف برنامه استفاده میشه.یعنی بعد از اینکه از کاربر گرفته شد، برای مثال به یک متد از یک کلاس داده میشه تا عملیاتی روش انجام بشه...در این حالت اگه شما به Validation ی که روی ورودی اعمال کردین اکتفا کنید، باید در اون متد این فرض بشه که ورودی معتبر هست...حالا اگه این متد رو جای دیگه که وروودیش از کاربر نیست بخواین استفاده کنید چی؟ یا اگه خواستین از کلاس توی یه پروژه دیگه استفاده کنید، مجبورید این پیش فرض ها رو اونجا هم در نظر بگیرین...
ضمن اینکه Exception ها همیشه در مورد ورودی از کاربر نیست.خیلی جاها از دسترس ما خارج هست، مثل کار با فایل...
جدای این موضوع، اگه شما بخواین سیاست استفاده از Exception رو پیش بگیرین، باید این کار رو به صورت یکپارچه انجام بدین.شما مثلا کد های NET. رو که نگاه کنید، هر متد، لیستی از Exception هایی که ممکنه درش روی بده رو مشخص کرده، و در همه کلاس ها، به صورت یکپارچه این موضوع پیاده شده...نه فقط در یک قسمت...

علی متقی پور
یک شنبه 04 فروردین 1392, 13:10 عصر
اصلا و ابدا با آقا یا خانم plus موافق نیستم
try...catch یه روش هزینه بر برای سیستمه و نباید ازش الکی استفاده کرد. جاییکه با ولیدیتور میشه کار کرد نیازی بهش نیست.
توجه کن ولیدتور را شما چیزی نبین که در UI اعمال میشه. شما ولیدیتور را هر جایی میتونی بیاری.
اصولا بنظر من باید هر متدی خودش بتونه مشکلات خودش رو هندل کنه. یعنی بفرض اگر میخواد یه استرینگ بگیره این حساب رو بکنه که اصلا ممکنه null بهش داده بشه و اونو هندل کنه. اینکارم نیازی به try...catch نداره بلکه با شرط گذاشتن میشه که انجامش داد.
البته من از نظر فنی نمیدونم چرا، ولی اونچه که میدونم اینه که try...catch باعث سربار اضافه میشه و استفاده ازش فقط در مواقع خاص بصرفه هست

Programmer 1
یک شنبه 04 فروردین 1392, 21:18 عصر
تا حدودی با حرف های آقای/خانم plus و تاحدودی هم با آقای متقی پور موافقم، اصولا ما اینجا با انتخاب ها سر و کار داریم، مشکل نه از Exception و نه از اعتبار سنج هاست، مشکل در کجا استفاده کردن از این روش هاست؟
انتخاب بین کارایی برنامه یا نگهداری برنامه؟
اگر هدفمون نگهداری برنامه باشه و به کارایی هم نخواهیم زیاد لطمه وارد کنیم پس فقط باید در جاهای خاصی ازش استفاده کنیم؟ این جاهای خاص کجاهاست؟ سوال اصلی من اینه؟

plus
دوشنبه 05 فروردین 1392, 00:26 صبح
اصلا و ابدا با آقا یا خانم plus موافق نیستم
try...catch یه روش هزینه بر برای سیستمه و نباید ازش الکی استفاده کرد. جاییکه با ولیدیتور میشه کار کرد نیازی بهش نیست.
توجه کن ولیدتور را شما چیزی نبین که در UI اعمال میشه. شما ولیدیتور را هر جایی میتونی بیاری.
اصولا بنظر من باید هر متدی خودش بتونه مشکلات خودش رو هندل کنه. یعنی بفرض اگر میخواد یه استرینگ بگیره این حساب رو بکنه که اصلا ممکنه null بهش داده بشه و اونو هندل کنه. اینکارم نیازی به try...catch نداره بلکه با شرط گذاشتن میشه که انجامش داد.
البته من از نظر فنی نمیدونم چرا، ولی اونچه که میدونم اینه که try...catch باعث سربار اضافه میشه و استفاده ازش فقط در مواقع خاص بصرفه هست
1.در اینکه استفاده از Validatior ها میتونه مناسب باشه شکی درش نیست، موضوع اینه Exception ها فقط در مورد ورودی کاربر نیست.
2.بله هر جایی که میشه با شرط بررسی کرد نیازی به Exception نیست، ولی خیلی جاها، مثل مثالی که زدم، نمیتونید با شرط چک کنید.
3.Performance ی که Try Catch کاهش میده، برای یک نرم افزار Real Time شاید با اهمیت باشه، اما به نظر میاد دوستان بیشتر با #C نرم افزار های Business ی کار میکنن.برای یک نرم افزاری که وقتی کابر یک دکمه مثلا ثبت رو میزنه یک اتصال تحت شبکه به SQL میره و ... اصلا اون کاهش Performance حساب نیست.
4.استفاده از Exception ها فقط معنیش استفاده از Try Catch نیست...خیلی جاها فقط به throw نیازه.
5.شما در #C دارید از NET. استفاده میکنید.کافیه وقتی اسم یک متد رو مینویسید، منتظر باشید تا توی Tooltip، لیست Exception هایی که هر متد ممکنه throw کنه رو ببینید.اکثر متد های کلاس های NET. بدون Excecption نیستند.برنامه نوشتن بدون در نظر گرفتن این exceptionها، مبتدیانه هست.

RED-C0DE
دوشنبه 05 فروردین 1392, 01:16 صبح
همونطور ک گفتن exception management هزینه بر هست و نباید هرجا (در صورتی ک راه دیگه ای وجود داشته باشه) استفاده بشه
همونطور ک گفته شد با کمک بررسی ها و اعمال validation مناسب قبل از عملیاتی ک می شه صحتشون رو بررسی کرد ، می شه مابقی کار رو تضمین شده کرد و نیازی ب سربار ناشی از خوردن ب exception نداشته باشیم

از طرف دیگه شرایط مختلفی هستن ک مجبور ب استفاده از exception handling هستیم ک بعضیاشو گفتن
از جمله ، وقتی با ی resource خارجی و ناپایدار کار می کنیم ک یک جعبه سیاه هست و ما نمی تونیم ب عملکردش مطمئن باشیم مثل شبکه ، دیتابیس ، فایل، ...
یا استفاده از کامپوننتی ک ب ناچار مجبورمون می کنه (ب دلایل مختلف) استفاده از یک متودش رو در بلاک try/catch بگنجونیم
و جاهای دیگه ای ک گفته شد بعضیاش..


در مورد اینکه کجا و کی باید از exception handling استفاده کرد اگه بخواین خیلی ریز و دقیق بشین باید تو طراحی فریمورک و ساختار زبان ریز بشین و مطالعه کنید ، اینکه در هر exception throwing ای ک رخ می ده مدیریت حافظه و آزاد سازی سلسله مراتبی stack و مدیریت اشاره گرهای برنامه ب چ صورت انجام می شه، هزینه مربوط ب ایجاد آبجکت مربوط ب exception برای throw شدن چقدره (برای همین می گن ک اگه exception ای از لایه درونی اومد اگه می خواین دوباره throw ش کنید و باز ب ی لایه بالاتر بفرستینش، فقط اون رو throw کنید نه اینکه throw new Exception کنید و یک آبجکت جدید بسازید برای اینکار)
و ...

در نهایت ممکنه ب جایی برسیم ک باید تصمیم بگیریم الان کارایی برامون مهمتره یا پایداری برنامه
بعضی جاها چیزای دیگه ای بیشتر از کارایی/performance برامون اهمیت داره و باید تامین بشه...
ب قول John Skeet: (http://www.yoda.arachsys.com/csharp/exceptions2.html)


If you ever get to the point where exceptions are significantly hurting your performance, you have problems in terms of your use of exceptions beyond just the performance.

In other words, in cases where performance is an important criterion for deciding not to use exceptions, there are other criteria which would also suggest avoiding exceptions for those cases - and those criteria are probably more important than the performance.



یک مقاله خوب هم در لینک زیر هست در این زمینه:
http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

علی متقی پور
دوشنبه 05 فروردین 1392, 03:30 صبح
1.در اینکه استفاده از Validatior ها میتونه مناسب باشه شکی درش نیست، موضوع اینه Exception ها فقط در مورد ورودی کاربر نیست.
2.بله هر جایی که میشه با شرط بررسی کرد نیازی به Exception نیست، ولی خیلی جاها، مثل مثالی که زدم، نمیتونید با شرط چک کنید.
3.Performance ی که Try Catch کاهش میده، برای یک نرم افزار Real Time شاید با اهمیت باشه، اما به نظر میاد دوستان بیشتر با #C نرم افزار های Business ی کار میکنن.برای یک نرم افزاری که وقتی کابر یک دکمه مثلا ثبت رو میزنه یک اتصال تحت شبکه به SQL میره و ... اصلا اون کاهش Performance حساب نیست.
4.استفاده از Exception ها فقط معنیش استفاده از Try Catch نیست...خیلی جاها فقط به throw نیازه.
5.شما در #C دارید از NET. استفاده میکنید.کافیه وقتی اسم یک متد رو مینویسید، منتظر باشید تا توی Tooltip، لیست Exception هایی که هر متد ممکنه throw کنه رو ببینید.اکثر متد های کلاس های NET. بدون Excecption نیستند.برنامه نوشتن بدون در نظر گرفتن این exceptionها، مبتدیانه هست.

با این حرفاتون موافقم ولی پست قبلیتون حرفهای دیگه ای زده بودید.
بنده متاسفانه از جزئیات فنی قضیه چیزی نمیدونم و واقعا سوال ایجاد کننده تاپیک سوال منم هست ولی چیزیکه برام مسلمه اینه که یک متد، کلاس و ... زمانی یه کامله که خودش خطاهاش رو تا حد ممکن هندل کنه. از این نظر شاید من بعضی چیزها تو دان نت هم انتقاد داشته باشم. مثلا عرض میکنم شما یه متغیر استرینگ بنام strText تعریف کن. بعد بهش مقدار null رو بده. بعد در ادامه بنویس strText.Length بعد خواهی دید که برنامه خطا میده. بنظر من این خیلی جالب نیست. اشکال کار هم اینجاست که اینتیجر تو دات نت نمیتونه null باشه. خب این یعضی ضعف. اگر این مشکل حل شه خیلی جاها اصلا استثنائی رخ نمیده.
حالا ما که کدهای دات نت رو نمیدونیم چطوریه ولی من بشخصه خودم سعی میکنم هر وقت یک کلاس یا متد برای کاری ایجاد میکنم جوری باشه که حتی اگر یه سادیسم هم باهاش کار کرد نونه ازش ارور بگیره. اونم ترجیحا از طریق شرط گذاشتن نه try...catch

plus
دوشنبه 05 فروردین 1392, 23:42 عصر
با این حرفاتون موافقم ولی پست قبلیتون حرفهای دیگه ای زده بودید.
بنده متاسفانه از جزئیات فنی قضیه چیزی نمیدونم و واقعا سوال ایجاد کننده تاپیک سوال منم هست ولی چیزیکه برام مسلمه اینه که یک متد، کلاس و ... زمانی یه کامله که خودش خطاهاش رو تا حد ممکن هندل کنه. از این نظر شاید من بعضی چیزها تو دان نت هم انتقاد داشته باشم. مثلا عرض میکنم شما یه متغیر استرینگ بنام strText تعریف کن. بعد بهش مقدار null رو بده. بعد در ادامه بنویس strText.Length بعد خواهی دید که برنامه خطا میده. بنظر من این خیلی جالب نیست. اشکال کار هم اینجاست که اینتیجر تو دات نت نمیتونه null باشه. خب این یعضی ضعف. اگر این مشکل حل شه خیلی جاها اصلا استثنائی رخ نمیده.
حالا ما که کدهای دات نت رو نمیدونیم چطوریه ولی من بشخصه خودم سعی میکنم هر وقت یک کلاس یا متد برای کاری ایجاد میکنم جوری باشه که حتی اگر یه سادیسم هم باهاش کار کرد نونه ازش ارور بگیره. اونم ترجیحا از طریق شرط گذاشتن نه try...catch
در مورد مثالتون، وقتی شما یک متدی نوشتی که یک ورودی روشته میگیره و عملی روش انجام میده، شما به ازای ورودی null میخوای چیکار کنی؟ مثلا null یا یه خروجی خاص مثل 0 برگردونی؟
بر اساس اونچیزی که در کد های دات نت دیدم، اگه این متد private باشه، با فرض اینکه نباید یه چنین پارامتری به این متد ارسال شده باشه (اشکال در کد نویسی نویسنده کلاس هست)، معملا یک Assert بررسی Null بودن رو انجام میده، ولی اگه متد public باشه، ایراد از فراخواننده هست و در اغلب اوقات (اگه در همش نباشه) یک NullReferenceException توسط متد throw میشه.
در واقع فرض این هست که اطلاعات از بیرون ممکنه نامعتبر بیان، ولی درون کلاس نباید اطلاعات نامعتبر وجود داشته بشه.بخش Defensive Programming از کتاب Code Complete رو بهتون پیشنهاد میکنم.
در ضمن شما میتونی کل کد های NET. رو در Source Reference مایکروسافت ببینید.متد های public کلاس ها، اغلب در ازای وروودی نامعتبر، Exception تولید میکنن و متد های private، بیشتر Assert.

علی متقی پور
سه شنبه 06 فروردین 1392, 00:58 صبح
فکر میکنم یا حرفهای من خیلی سادست یا حرفای شما زیادی پیچیده.
Private یا public بودن متد ربطیبه به بحث ورود مقدار نال نداره. یک برنامه اینترپرایز لحظه به لحظه با قسمت های خارج ازکنرتل خودش در ارتباطه. هیچ برنامه نویسی با نوشتن کد نمیتونه کاری کنه مثلا دیتا بیس کرش نکنه. یا هزار جور مشکل دیگه که ممکنه پیش بیاد. تولید مقادیر نال در همه جای برنامه ممکنه ایجاد بشن. بله اگر من بفرض نوشتم "a="Ali قطعا تو خط بعدی کدم این احتمال رو نمیدم که a برابر نال باشه. اما اگر این متغیر قراره از دیتا بیس مقدار بگیره هیچ تضمینی وجود نداره که نال نشه. پس من باید خودم این مساله رو کنترل کنم. ممکنه شما از لینک برای کوئری نویسی استفاده کنی. لینک از بعضی کدها ساپروت نمیکنه. مثلا نمیتونی اعضای آرایه رو تو لینک بیاری. خب کد شما ظاهرش درسته. اما موقع اجرا خطا پیش میاد. اصولا هر جا که کار از دست کد ما خارجه باید این احتمال رو بدیم. ولی بنظر من اینها اصلا جزء استثنائات نیستن. بلکه طبیعیه. یعنی نباید زود به کاربر ارور بدیم. بلکه برنامه طبق سناریو خودش باید مساله رو هندل کنه. اگر با یه سیستم نسبتا قدیمی کار کنید میبینید که ارور تایم آوت برای ارتباط با دیتا بیس یه چیز طبیعیه. حالا شما برنامه نوشتی ده هزار خط بعد میخوای به کاربر ارور تایم آوت نشون بدی؟ خب این مسلما غیر عقلانیه. مطمئنا شما باید این سماله رو هندل کنی. مثلا اگر چنین چیزی رخ داد سعی کنه یک سا دوبار دیگم تلاش کنه. و اگر موفق نشد سعی کنه اگر میتونه زمان مجاز برای ارتباظ با دیتا بیس رو افایش بده.
بهرحال از بحث اصلی دور نشیم. کاش یکی میومد و میگفت کجاها باید اکسپشن ها هندل بشن :-)

مهدی هادیان2
یک شنبه 18 فروردین 1392, 23:07 عصر
بسم الله الرحمن الرحیم
با سلام
از دوستانی که در تاپیک شرکت کردند تشکر می کنم؛ بحث بسیار کاربردی ست.
یک سوال برام پیش اومده:
خواستم بدونم موارد کاربرد throw دقیقا چیه؟
بنده در کلاس هام یک متغیر از نوع رشته ای تعریف کردم به شکل زیر

public string Message
{
get
{
return message;
}
}
حالا فرض بفرمائید می خواهیم به بانک وصل شویم کدی مثل زیر:

try
{
DBConnection.Open();
message = ".ارتباط با بانک اطلاعاتی برقرار گردید";
return true;
}
catch (SqlException)
{
message = ".ارتباط با بانک اطلاعاتی برقرار نگردید";
return false;
}

و بدین ترتیب هیچ گاه نیازی به throw پیدا نکردم. و در لایه BL , UL هم از متغیر Messageی که از لایه های پایین وجود دارد استفاده می کنم.
با سپاس

علی متقی پور
دوشنبه 19 فروردین 1392, 11:25 صبح
تا اونجا که من میدونم throw برای این مواقعیه که شما عادمانه و آگاهانه بروز یک استثناء رو گزارش میکنید. یعنی فرض کنید شما بدنبال یک رکورد خاص تو دیتا بیس هستید و اونو سلکت میکنید. فرض هم بر این هست که حتما باید این رکورد در دیتا بیس باشه. بعد شرط میذارید که اگر نبود حتما اشکالی رخ داده و یک استثناء ایجاد میکنید. در اینجا عملا هیچ خطایی رخ نداده بلکه شما آگاهانه و عامدانه یک خطا ایجاد میکنید و میگید که سیستم قطعا ایراد داره

morteza_mt5
چهارشنبه 18 اردیبهشت 1392, 10:46 صبح
دوستان :لبخندساده:مدیریت خطا و اسنثناء مطمئنا هیجان انگیزترین قسمت ساخت یک نرم افزار نیست ، اما برای یه برنامه Enterprise لازمه .
بذارین براتون یه مثال بزنم :
فرض کنید خطایی در لایه امنیت برنامه شما رخ داده و اگه قرار باشه خطای به وجود اومده رو مدیریت نکنین ممکن است اطلاعات حساسی به کاربر نمایش داده شود . خوب باید خطای به وجود اومده رو با خطای دیگه ای Replace کنین تا کاربر متوجه خطای اصلی نشه . و خطای اصلی رو هم جای دیگه Log کنین که Admin برنامه بتونه به اصلاح خطا بپردازه .(البته روش های دیگه ای هم هست)
این خودش یه Pattern-e و Pattern های دیگه ای برای مدیریت و Handle کردن خطا وجود دارند و با توجه به استراتژی های مختلفی مورد استفاده قرار میگیرن . من به شما یه Library رو معرفی می کنم که به راحتی می تونین این خطا ها رو مدیریت کنین . این Library برای تیم Pattern And Practices شرکت مایکروسافته و خیلی هم قدرتمنده و در حال حاضر هم نسخه 6 اون امده .
اگه استقبال شد روش استفاده رو هم میذارم .
اینم لینک Enterprise Library

http://msdn.microsoft.com/en-us/library/ff664698%28v=pandp.50%29.aspx

علی متقی پور
پنج شنبه 19 اردیبهشت 1392, 12:24 عصر
دوستان :لبخندساده:مدیریت خطا و اسنثناء مطمئنا هیجان انگیزترین قسمت ساخت یک نرم افزار نیست ، اما برای یه برنامه Enterprise لازمه .
بذارین براتون یه مثال بزنم :
فرض کنید خطایی در لایه امنیت برنامه شما رخ داده و اگه قرار باشه خطای به وجود اومده رو مدیریت نکنین ممکن است اطلاعات حساسی به کاربر نمایش داده شود . خوب باید خطای به وجود اومده رو با خطای دیگه ای Replace کنین تا کاربر متوجه خطای اصلی نشه . و خطای اصلی رو هم جای دیگه Log کنین که Admin برنامه بتونه به اصلاح خطا بپردازه .(البته روش های دیگه ای هم هست)
این خودش یه Pattern-e و Pattern های دیگه ای برای مدیریت و Handle کردن خطا وجود دارند و با توجه به استراتژی های مختلفی مورد استفاده قرار میگیرن . من به شما یه Library رو معرفی می کنم که به راحتی می تونین این خطا ها رو مدیریت کنین . این Library برای تیم Pattern And Practices شرکت مایکروسافته و خیلی هم قدرتمنده و در حال حاضر هم نسخه 6 اون امده .
اگه استقبال شد روش استفاده رو هم میذارم .
اینم لینک Enterprise Library

http://msdn.microsoft.com/en-us/library/ff664698%28v=pandp.50%29.aspx

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

morteza_mt5
دوشنبه 23 اردیبهشت 1392, 15:40 عصر
دوست عزیز من متوجه موضوع تایپبک شدم و دراین که شما هندل کردن رو بلدی شکی نیست .
اگه به لینک سری زده بودین متوجه میشدین که خود سایت مایکروسافت چرایی استفاده از Exception Handling رو برای Developer ها قرار داده و توضیحات کامل رو گذاشته
اینم لینکش
http://msdn.microsoft.com/en-us/library/ff649052.aspx
اگه دنبال یادگیری هستی به سایت بالا سری بزنی بد نیست .
و لینک زیر هم میتونه کمکت کنه :
http://msdn.microsoft.com/en-us/library/ms229014%28VS.80%29.aspx
البته باید بگم این لینک هایی رو که اینجا گذاشتم نحوه استفاده از Exception Handling Block رو آموزش نمیده ، بلکه میگه چه موقع باید از اون استفاده کرد و چرا ؟
چرخ ، ساخته شده و ما باید اونو توسعه بدیم نه اینکه از اول بسازیمش .
با تشکر .
:لبخندساده:

علی متقی پور
دوشنبه 23 اردیبهشت 1392, 20:27 عصر
دوست عزیز من متوجه موضوع تایپبک شدم و دراین که شما هندل کردن رو بلدی شکی نیست .
اگه به لینک سری زده بودین متوجه میشدین که خود سایت مایکروسافت چرایی استفاده از Exception Handling رو برای Developer ها قرار داده و توضیحات کامل رو گذاشته
اینم لینکش
http://msdn.microsoft.com/en-us/library/ff649052.aspx
اگه دنبال یادگیری هستی به سایت بالا سری بزنی بد نیست .
و لینک زیر هم میتونه کمکت کنه :
http://msdn.microsoft.com/en-us/library/ms229014%28VS.80%29.aspx
البته باید بگم این لینک هایی رو که اینجا گذاشتم نحوه استفاده از Exception Handling Block رو آموزش نمیده ، بلکه میگه چه موقع باید از اون استفاده کرد و چرا ؟
چرخ ، ساخته شده و ما باید اونو توسعه بدیم نه اینکه از اول بسازیمش .
با تشکر .
:لبخندساده:

یه بنده خدائی تو این فروم یه تاپیکی زده بود و یهس والی رو مطرح کرده بود. در اخرش هم عاجزانه درخواست کرده بود که لطفا کسی نتایج صفحه اول گوگل رو براش نذاره.
داداش گلم، فدات شم اینجا با یه مشت معلول ذهنی طرف نیستی که نیاز داشته باشن لینک msdn رو بهشون بدی.
درد و بلات بخوره تو اون سرم من بیسوادم شما با سواد. من الان یه سوالی ازت میپرسم که مثل عنوان تاپیک کلی نباشه. شما بطور جزئی جوابش رو بمن بده و برای من آموزش سرچ گوگل نذار.
من یه متدی دارم که در داخلش نیاز داره مثلا یه string یا integer را از دیتا بیس بخونه و براساس اون یه فعالیتی انجام بده و بعد یه string یا integer برگردونه. از این متد هم در داخل یه بیزینس دیگه استفاده می شه.
همه میدونن که یک سلکت ممکنه دچار استثناء بشه (مثلا کانکشن استرینگ کلا غلط باشه) خب حالا ما تصمیم میگیریم سلکتمون رو داخل یه try بذاریم. خب تکلیف ادامه کار چیه؟ بهرحال متد ما نیاز به خروجی داره. بفرض اگر صفر یا null برگردونه خب ادامه بیزنس هم دچار مشکل میشه. این چرخه هندل کردن باید چطوری ادامه پیدا کنه؟آیا باید کل بیزینسمون رو داخل یه try بنویسیم؟!!! اینکه نه معقوله نه ممکن (البته ممکنه شما بگی معقول و ممکنه) از طرفی هندل کردنش باید چطوری باشه. فرض کن من تو قسمت catch اون باید چی بگم؟ بگم بیزینس قطع بشه و ادامه نده بقیش رو؟ با چه دستوری؟ بگم break کنه؟ خب اون میره ادامه کد رو از داخل بیزینس اجرا میکنه. بگه کلا هیچ اقدامی نکنه؟ یعنی بیا دستوراتم رو هم ولیدیت کنم که اگر هیچ استثنائی رخ ندا اجرا بشن؟
من مشکل عزیزی که تاپیک رو زده نمیدونم ولی خود بیسوادم دچار این مشکلاتم. حالا اگر بنظرتون کسی که میاد وقت میذاره و تاپیک میزنه و سوال مطرح میکنه میخواد که شما لینک msdn رو بهش بدید این دیگه زاویه دید شماست.

FastCode
دوشنبه 23 اردیبهشت 1392, 22:02 عصر
دستورات try/catch همیشه باید در پایینترین سطح ممکن نوشته بشن.و در Application های bussiness اصولا نباید زیاد استفاده بشن چون شما باید تمام case ها رو در نظر بگیرید نه اینکه صبر کنید خطا بده بعد یه کاریش بکنید یا بی صدا از روش رد بشید.

tooraj_azizi_1035
دوشنبه 23 اردیبهشت 1392, 22:22 عصر
Exceptions and Exception Handling (C#‎ Programming Guide) (http://msdn.microsoft.com/en-us/library/ms173160.aspx)

علی متقی پور
سه شنبه 24 اردیبهشت 1392, 01:49 صبح
دستورات try/catch همیشه باید در پایینترین سطح ممکن نوشته بشن.و در Application های bussiness اصولا نباید زیاد استفاده بشن چون شما باید تمام case ها رو در نظر بگیرید نه اینکه صبر کنید خطا بده بعد یه کاریش بکنید یا بی صدا از روش رد بشید.

پائین ترین سطح؟
application های bussiness؟
case ها؟
مهندس عزیزم میشه بیشتر در مورد اینها توضیح بدی؟!!!!!

البته من شما رو میشناسم و میدونم علمتون بسییار بیشتر از بنده است ولی فکر میکنم در استفاده از وآژگان دچار خطا شدید.
پائین ترین سطح یه کد کجا حساب میشه؟
زبان های برنامه نویسی از جهت اینکه چقد به زبان اصلی ماشین نزدیکن ب زبان های سطح بالا و پائین تقسیم میشن ولی در مورد کد نویسی من تا الان این اصطلاح رو نشنیده بودم. البته جعل اصطلاح برای بیان مقصود یه کار خوب و پسندیدس ولی من فکر نمیکنم کد نوشته شد در یه متد مثلا سطح پائین و کد نوشته شده در کلاس سطح بالا حساب بشه. واقعا نمیتونم از روی کلمات معنای حرف شما رو متوجه بشم. ولی خب چون بحث ما در مورد استثنائه میتونم بفهمم که مقصود شما چیه. مقصود شما اینه که ما try رو در نزدیک ترین حالت به محل استثنائ قرار بدیم یعنی مثلا بنویسیم

try{ Con.Open() } catch{}

خب این دقیقا همون چیزیه که من عرض کردم و خب همه هم همین روش رو استفاده میکنن. ولی بحث اینجاست که وقتی شما در یک متدی که جزئی از یک فرایند و یک ماژوله دچار استثناء میشی باری ادامه اون فرایند باید چکار کنی؟
شما از اصطلاح عجیب application های bussiness استفاده کردی که احتمالا منظورت لایه بیزینس اپلیکیشن بوده.
خب فدات شم من می خوام همه بقول شما case ها و بقول من حالات ممکن رو در نظر بگیرم. متد من که باید string بر میگردونده به دلیل وقوع استثناء حالا Null بر گردوندنه. من براساس این ورودی قرار بوده هزار جور محاسبات انجام بدم. پس باید بیام خروجی متدم رو چک کنم که اگر Null بود ما بقی بیزینس انجام نشه و برنامه کلا روندش رو متوقف کنه. خب حالا شما در یک اپلیکیشن اینترپرایز چطوری میتونید همه حالات ممکن رو اینطوری هندل کنید؟ واقعا حتی تصورش هم سخته که ما بیائیم برای همه حالا مدام شرط بذاریم. دیگه اصلا پر فورمنس برای برنامه باقی نمیمونه.
یک برنامه با ترانز اکشن های زیاد که هر لحظه با دیتا بیس در حال ارتباطه هر ثانیه باید ده ها بار شرط رو چک کنه تا مطمئن شه استثنائی رخ نداده باشه. بنظر من اصلا منطقی نیست.
من یه برنامه نویس خیییییییییییییلی معمولیم. کاش افرادیکه با برنامه های غول کار کردن میمومدن میگفتن واقعا چطوری کدشون رو مینویسن. البته این رو هم بگم ها من فکر میکنم خیلی از برنامه های قدرتمند استثنائاتی رو که احتمال وقوعشون کمه رو اصلا هندل نمیکنن!!!!
شاید حرفم عجیب باشه ولی من فکر میکنم اینطور باشه. خلی اوقات شاید این حق برای نرم افزار شناخته شده باشه که غاطی کنه. شاید ماهی یک بار غاطی کردن یک اپلیکیشن بسیار صدمه کمتری بهش بزنه تا اینکه با گذاشتن شرط و شروط های زیاد پرفورمنسش رو بکشیم.

FastCode
سه شنبه 24 اردیبهشت 1392, 08:07 صبح
void proc1()
{
proc2();
proc3();
}

void proc2()
{
try
{
externalcode1();
}
catch
{
proc4();
}
}
void proc3()
{
externalcode2();
}
void proc4()
{
externalcode1_failsafe();
}
فرض کنید در این کد شما Exception Handling رو ببرید به proc1
اتفاقی که میافته اینه:
شما مجبورید بخشی از منطق proc2 رو به proc1 ببرید.
برای این که Exception های proc2 و proc3 رو جدا کنید باید دو تا try/catch پشت سر هم در proc1 بنویسید.
باید تمام محلهایی که proc2 رو اجرا میکنند را جدا تغییر دهید.
به متغیر های درون متود برای بررسی خطا و راه حل های احتمالی دسترسی نخواهید داشت.

باور کن من همه رو شنیده بودم که استفاده کردم.
منظور از پایینترین سطح هم همون لایه های برناسمت.
bussiness application که همین برنامه های در پیت ملت هست که با DataSet مینویسن.
من تا الان با همین روش موفق بودم.شما نباید خیلی جاها اجازه null بدی که متودتون بتونه null برگدونه.اگر فکر میکنید سخته میتونید اول با اضافه کردن constraint های ورودی برنامتون و دیتابیس مشکل رو تا حدی کم کنید.
برای همین موارد هست که برنامه رو تست میکنند:
stress test
blackbox test
alpha test
beta test

شما باید در برنامتون از comment برای متود ها و property ها استفاده کنید که موقع نوشتن متوجه بشید یک procedure ممکن هست null برگردونه یا نه.

اسم Application غول نیار که من الان دارم روی یکی از همینها تنها کار میکنم.فکر میکنم ۶۰ ۷۰ نفری کم داشته باشم برای تموم کردنش.

علی متقی پور
سه شنبه 24 اردیبهشت 1392, 14:27 عصر
void proc1()
{
proc2();
proc3();
}

void proc2()
{
try
{
externalcode1();
}
catch
{
proc4();
}
}
void proc3()
{
externalcode2();
}
void proc4()
{
externalcode1_failsafe();
}
فرض کنید در این کد شما Exception Handling رو ببرید به proc1
اتفاقی که میافته اینه:
شما مجبورید بخشی از منطق proc2 رو به proc1 ببرید.
برای این که Exception های proc2 و proc3 رو جدا کنید باید دو تا try/catch پشت سر هم در proc1 بنویسید.
باید تمام محلهایی که proc2 رو اجرا میکنند را جدا تغییر دهید.
به متغیر های درون متود برای بررسی خطا و راه حل های احتمالی دسترسی نخواهید داشت.

باور کن من همه رو شنیده بودم که استفاده کردم.
منظور از پایینترین سطح هم همون لایه های برناسمت.
bussiness application که همین برنامه های در پیت ملت هست که با DataSet مینویسن.
من تا الان با همین روش موفق بودم.شما نباید خیلی جاها اجازه null بدی که متودتون بتونه null برگدونه.اگر فکر میکنید سخته میتونید اول با اضافه کردن constraint های ورودی برنامتون و دیتابیس مشکل رو تا حدی کم کنید.
برای همین موارد هست که برنامه رو تست میکنند:
stress test
blackbox test
alpha test
beta test

شما باید در برنامتون از comment برای متود ها و property ها استفاده کنید که موقع نوشتن متوجه بشید یک procedure ممکن هست null برگردونه یا نه.

اسم Application غول نیار که من الان دارم روی یکی از همینها تنها کار میکنم.فکر میکنم ۶۰ ۷۰ نفری کم داشته باشم برای تموم کردنش.


ممنون بابت توضیحاتت اما میدونی مشکل چیه مهندس.
اینکه ما از دیتابیسمون نتیجه ای خلاف اونچه پیش بینی میکردیم بدست بیاریم چیزی نیست که همیشه قابل پیش بینی باشه. ضمن اینکه متاسفانه string برخلاف integer قابلیت پذیرش نال رو هم داره و این دیگه دست من و شما نیست.
شما اگر دقت کنی تو دستورات لینک متدهای مربوط به خروجی گرفتن دو حالت دارن. یکی مثلا single و یکی SingleorDefault. یعنی در حالت اول خودش میگه اگر از رکورد مورد نظر من کمتر یا بیشتر از یه دونه بود بیا و خطا بده.

میدونی مهندس مشکل من کجاست. من هندل کردن خطا رو انجام میدم ولی نمیدونم اگر این خطا تو یه متد تو یه روال مثلا با 10 تا متد اتفاق افتاد تکلیف چیه. من کد شما رو متوجه شدم که فرمودی مسیر برنامه رو کلا تغییر میدیم ولی خب بحث خروجی چی میشه؟
تو یه برنامه ساده و کوچیک همه چی قابل کنترله ولی فرض کن یه برنامه مولتی ترد نوشتی و کلی کارهای پیچیده داره همزمان انجام میشه. اونوقت باید چکار کرد؟
بر میگردم به سوال تاپیک واقعا کجاها باید خطا رو هندل کرد؟ من فکر میکنم گاهی بعضی خطاها رو نباید هندل کرد. یعنی گاها هندل کردن بعضی شرایط واقعا ممکن نیست و بهتره بذاریم برنامه غاطی کنه. کما اینکه من بارها دیدم خود VS غاطی کرده و خودش را ریستارت کرده. یعنی هیچ هندلی وجود نداشته.

FastCode
سه شنبه 24 اردیبهشت 1392, 16:54 عصر
من بارها دیدم خود VS غاطی کرده و خودش را ریستارت کرده. یعنی هیچ هندلی وجود نداشته.
من ترجیح میدم خطا بده و یک ساعت کارم رو از دست ندم.
در برنامه های multi thread هم شما باید در تردی که دچار خطا شده به ترد های دیگه پیغام بدی که کارشون رو متوقف کنند.وقتی از ترد استفاده میکنید باید اصولش رو هم بلد باشید.استفاده از ترد همین نوشتن new Thread و lock فلان نیست.خیلی مطالب هست که باید در این برنامه ها لحاظ بشه.یکیش سیگنال دادن موقع خطا هست.

if you think its simple then you have misunderstood the problem.
شما باید در هر مرحله همه ی خطا های ممکن رو پیشبینی کنی.من الان کدی ندارم که براتون مثال بزنم.
اگر جاوا کار کرده باشید دقیقا متوجه میشید چی میگم.جاوا این شرط رو به برنامه نویس اجبار میکنه.

مهدی هادیان2
سه شنبه 24 اردیبهشت 1392, 17:15 عصر
بسم الله الرحمن الرحیم
با سلام
اگه یکی از دوستان بیاد و یک فرم طراحی کنه که بشه عملیات Insert ,... رو توش انجام داد. از طرفی کارهای مربوطه رو به لایه های مخصوص به خودش بفرسته و اونجا هندل انجام بشه؛ خیلی از مسائل حل میشه.
در حال حاضر شاید اگه حرفهامون یکی هم باشه امکان داره دچار سوء برداشت بشیم؛ چون در سطحی از انتزاعه. اگه ملموس بشه بهتر حرف های هم رو خواهیم فهمید.
با سپاس

علی متقی پور
سه شنبه 24 اردیبهشت 1392, 17:54 عصر
بسم الله الرحمن الرحیم
با سلام
اگه یکی از دوستان بیاد و یک فرم طراحی کنه که بشه عملیات Insert ,... رو توش انجام داد. از طرفی کارهای مربوطه رو به لایه های مخصوص به خودش بفرسته و اونجا هندل انجام بشه؛ خیلی از مسائل حل میشه.
در حال حاضر شاید اگه حرفهامون یکی هم باشه امکان داره دچار سوء برداشت بشیم؛ چون در سطحی از انتزاعه. اگه ملموس بشه بهتر حرف های هم رو خواهیم فهمید.
با سپاس

دقیقا منم فکر میکنم مشکل همین جاست.
یعنی کم سوادی من باعث شده نتونم منظورم رو دقیق برسونم هر چند که زیاد درموردش حرف زدم.
الان کد خاصی ندارم که اینجا بذارم ولی میتونم بعنوان گام اول یه مثال فرضی بنویسیم


public static string Ali(string strData)
{
int a = Method1(strData);

string b = Method2(a);

int c = Method3(b);

return Method4(c);
{



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

بعد از جواب این سوال ایشالا گام های بعدی رو بر میداریم :)

Programmer 1
سه شنبه 24 اردیبهشت 1392, 18:40 عصر
دقیقا منم فکر میکنم مشکل همین جاست.
یعنی کم سوادی من باعث شده نتونم منظورم رو دقیق برسونم هر چند که زیاد درموردش حرف زدم.
الان کد خاصی ندارم که اینجا بذارم ولی میتونم بعنوان گام اول یه مثال فرضی بنویسیم


public static string Ali(string strData)
{
int a = Method1(strData);

string b = Method2(a);

int c = Method3(b);

return Method4(c);
{



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

بعد از جواب این سوال ایشالا گام های بعدی رو بر میداریم :)

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

FastCode
سه شنبه 24 اردیبهشت 1392, 19:45 عصر
با این کد نمیشه کری کرد.اگر یک کد واقعی بزارید میتونم نشونتون بدم چطوری rollback میکنم و کجا catch میکنیم و چطوری به کاربر اطلاع میدیم که fail شده

علی متقی پور
سه شنبه 24 اردیبهشت 1392, 21:46 عصر
با این کد نمیشه کری کرد.اگر یک کد واقعی بزارید میتونم نشونتون بدم چطوری rollback میکنم و کجا catch میکنیم و چطوری به کاربر اطلاع میدیم که fail شده

:| کد واقعی معنیش چیه؟ با این حساب من باید یه سولوشن کامل بذارم که توش رابطه متد ها و کلاس ها مشخص باشه. این سوال فکر کنم خیلی ابتدایی و واضحه. امیدوارم کسی بتونه جوابش رو بده

مهدی هادیان2
چهارشنبه 25 اردیبهشت 1392, 11:38 صبح
بسم الله الرحمن الرحیم
با سلام
یک پروژه 3لایه پیدا کردم که با EF نوشته شده است؛ از لینک زیر میتونید دانلود کنید:
http://www.sattsoft.com/uploads/codes/3tierETF.zip
برخی از قسمت های مهم پروژه رو هم اینجا کپی میکنم تا دوستانی که تمایل دارند روی همین برنامه مباحث رو دنبال کنند راحت تر باشند.
کلاسی برای کتاب به شکل زیر ایجاد شده است:
Public Class Book
Private _id As Integer
Private _title As String
Private _subject As String
Private _description As String
Private _isbnno As String
Private _author As String

Public Sub New()

End Sub

Public Property BookID As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property Title As String
Get
Return _title
End Get
Set(ByVal value As String)
_title = value
End Set
End Property
Public Property Subject As String
Get
Return _subject
End Get
Set(ByVal value As String)
_subject = value
End Set
End Property
Public Property Description As String
Get
Return _description
End Get
Set(ByVal value As String)
_description = value
End Set
End Property
Public Property ISBN_No As String
Get
Return _isbnno
End Get
Set(ByVal value As String)
_isbnno = value
End Set
End Property
Public Property Author As String
Get
Return _author
End Get
Set(ByVal value As String)
_author = value
End Set
End Property

End Class

در کلاس BookDataAccess کلاسی برای ارتباط با دیتا بیس طراحی شده است:
Public Class BookDataAccess
Implements IDisposable

Dim entBook As BookEntities

Public Sub New()

End Sub
Function AddNewBook(ByVal obj As tblbook)
Dim objBook As New tblbook
objBook = obj
Try
Using entBook = New BookEntities
entBook.AddTotblbooks(objBook)
entBook.SaveChanges()
Return objBook.book_id
End Using
Catch ex As Exception
Throw
End Try
End Function
Public Sub UpdateBook(ByVal obj As tblbook)
Dim objBook As New tblbook

Try
Using entBook = New BookEntities
objBook = (From p In entBook.tblbooks
Where p.book_id = obj.book_id
Select p).FirstOrDefault
With objBook
.book_title = obj.book_title
.book_subject = obj.book_subject
.book_description = obj.book_description
.isbn_no = obj.isbn_no
.author = obj.author
End With

entBook.SaveChanges()
End Using
Catch ex As Exception
Throw
End Try
End Sub

Function Load_BookDetails(ByVal iBookID As Long)
Dim objBook As New tblbook
Try
Using entBook = New BookEntities
Dim qryUsers = From p In entBook.tblbooks
Where p.book_id = iBookID
Select p

Dim luser As List(Of tblbook) = qryUsers.ToList
If luser.Count > 0 Then
Return luser.First
Else
Return objBook
End If
End Using
Catch ex As Exception
Throw
End Try
End Function
Public Sub DeleteBook(ByVal iBookID As Long)
Dim objBook As New tblbook
Try
Using entBook = New BookEntities
objBook = (From p In entBook.tblbooks
Where p.book_id = iBookID
Select p).FirstOrDefault

entBook.DeleteObject(objBook)
entBook.SaveChanges()
End Using
Catch ex As Exception
Throw
End Try
End Sub
Function Load_BookList()
Try
Using entBook = New BookEntities
Dim qry = From p In entBook.tblbooks
Select p
Dim result As List(Of tblbook) = qry.ToList()
Return result
End Using
Catch ex As Exception
Throw New Exception(ex.InnerException.ToString)
End Try
End Function

#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If

' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub

' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub

' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

End Class

BusinessLayer لایه منطقی ست:
Imports DAL
Public Class BusinessLogic
Inherits BaseClass
Implements IDisposable
Dim daBook As BookDataAccess

Public Sub New()

End Sub
Function AddNewBook(ByVal obj As Book)
Dim objBook As New tblbook
Try
With objBook
.book_title = obj.Title
.book_subject = obj.Subject
.book_description = obj.Description
.isbn_no = obj.ISBN_No
.author = obj.Author
End With
Using daBook = New BookDataAccess
Return daBook.AddNewBook(objBook)
End Using
Catch ex As Exception
Throw
End Try
End Function
Public Sub UpdateBook(ByVal obj As Book)
Dim objBook As New tblbook
Try
With objBook
.book_id = obj.BookID
.book_title = obj.Title
.book_subject = obj.Subject
.book_description = obj.Description
.isbn_no = obj.ISBN_No
.author = obj.Author
End With
Using daBook = New BookDataAccess
daBook.UpdateBook(objBook)
End Using
Catch ex As Exception
Throw
End Try
End Sub
Public Sub DeleteBook(ByVal iBookID As Long)
Using daBook = New BookDataAccess
daBook.DeleteBook(iBookID)
End Using
End Sub
Function Load_BookList() As DataTable
Dim dt As New DataTable
Try
Using daBook = New BookDataAccess
dt = ToDataTable(daBook.Load_BookList())
Return dt
End Using
Catch ex As Exception
Throw
End Try
End Function
Function Load_BookDetails(ByVal iBookID As Long) As Book
Dim objBookEnt As New tblbook
Dim objBook As New Book
Try
Using daBook = New BookDataAccess
objBookEnt = daBook.Load_BookDetails(iBookID)
With objBook
.BookID = objBookEnt.book_id
.Title = objBookEnt.book_title
.Subject = objBookEnt.book_subject
.Description = objBookEnt.book_description
.ISBN_No = objBookEnt.isbn_no
.Author = objBookEnt.author
End With
Return objBook
End Using
Catch ex As Exception
Throw
End Try
End Function
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If

' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub

' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub

' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

End Class

و نهایتا در frmBook از لایه منطقی استفاده کرده است:
Imports BLL
Public Class frmBook
Dim objBLogic As BusinessLogic
Dim objBook As Book
Dim dt As New DataTable

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Dim res As New DialogResult
Try
res = MsgBox("Do you really want to save changes?.", MsgBoxStyle.YesNo)
If res = Windows.Forms.DialogResult.Yes Then
With objBook
.Title = Me.txtTitle.Text
.Subject = Me.txtSubject.Text
.Description = Me.txtDescription.Text
.ISBN_No = Me.txtISBN.Text
.Author = Me.txtAuthor.Text
End With

Using objBLogic = New BusinessLogic
If Not IsNothing(Me.txtID.Tag) Then
objBLogic.UpdateBook(objBook)
Else
Me.txtID.Text = objBLogic.AddNewBook(objBook)
Me.txtID.Tag = Me.txtID.Text
End If

End Using
MsgBox("Record has been saved.")
End If

Catch ex As Exception
MsgBox(ErrorToString)
End Try
End Sub

Private Sub btnNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNew.Click
objBook = New Book
ClearFields()
End Sub
Private Sub Load_Record()
objBook = New Book

Try
Using objBLogic = New BusinessLogic

End Using
Catch ex As Exception
MsgBox(ErrorToString)
End Try
End Sub

Private Sub frmBook_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
RefreshResult()
Load_Book_Detail(Me.dtResult.Item(0, Me.dtResult.CurrentRow.Index).Value)
End Sub

Private Sub btnRefresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefresh.Click
RefreshResult()
End Sub
Private Sub RefreshResult()
Try
Using objBLogic = New BusinessLogic
dt.Rows.Clear()
dt = objBLogic.Load_BookList()
Me.dtResult.DataSource = dt
End Using

Catch ex As Exception
MsgBox(ErrorToString)
End Try
End Sub
Private Sub dtResult_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtResult.DoubleClick
Load_Book_Detail(Me.dtResult.Item(0, Me.dtResult.CurrentRow.Index).Value)
End Sub
Private Sub Load_Book_Detail(ByVal iBookID As Long)
objBook = New Book
Using objBLogic = New BusinessLogic
objBook = objBLogic.Load_BookDetails(iBookID)
With objBook
Me.txtID.Text = .BookID
Me.txtTitle.Text = .Title
Me.txtSubject.Text = .Subject
Me.txtDescription.Text = .Description
Me.txtISBN.Text = .ISBN_No
Me.txtAuthor.Text = .Author
Me.txtID.Tag = .BookID
End With
End Using
End Sub
Private Sub ClearFields()
Me.txtID.Tag = Nothing
Me.txtID.Text = ""
Me.txtTitle.Text = ""
Me.txtSubject.Text = ""
Me.txtDescription.Text = ""
Me.txtISBN.Text = ""
Me.txtAuthor.Text = ""
End Sub

Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
Me.Close()
End Sub

Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click
Dim res As New DialogResult

res = MsgBox("Do you really want to delete data?", MsgBoxStyle.YesNo)
If res = Windows.Forms.DialogResult.Yes Then
Using objBLogic = New BusinessLogic
objBLogic.DeleteBook(Me.txtID.Tag)
End Using
MsgBox("Record has been deleted.")
RefreshResult()
Load_Book_Detail(Me.dtResult.Item(0, Me.dtResult.CurrentRow.Index).Value)
End If
End Sub
End Class

قطعا میشه این پروژه رو بهترش کرد ولی فعلا برای اینکه کارمون راه بیندازه خوبه. به نظرم اگه دوستان روی همین پروژه توضیحاتشون رو بفرمایند ان شاالله مفید واقع خواهد شد.
موفق باشید.
منبع:http://www.sattsoft.com/sourcecodes/details/1/6/entity-framework-3-tier-architecture.html

FastCode
چهارشنبه 25 اردیبهشت 1392, 12:46 عصر
همین قسمت کد که گزاشتید بیش از ۶۰ تا ایراد داره.(تا ۴۰ بیشتر نشمردم.قسمت آخر رو با تناسب حساب کردم)
سعی میکنم اول ایراداتش رو درست کنم و تبدیلش کنم به C# بعد بررسیش کنیم.

morteza_mt5
دوشنبه 30 اردیبهشت 1392, 10:13 صبح
یه بنده خدائی تو این فروم یه تاپیکی زده بود و یهس والی رو مطرح کرده بود. در اخرش هم عاجزانه درخواست کرده بود که لطفا کسی نتایج صفحه اول گوگل رو براش نذاره.
داداش گلم، فدات شم اینجا با یه مشت معلول ذهنی طرف نیستی که نیاز داشته باشن لینک msdn رو بهشون بدی.
درد و بلات بخوره تو اون سرم من بیسوادم شما با سواد. من الان یه سوالی ازت میپرسم که مثل عنوان تاپیک کلی نباشه. شما بطور جزئی جوابش رو بمن بده و برای من آموزش سرچ گوگل نذار.
من یه متدی دارم که در داخلش نیاز داره مثلا یه string یا integer را از دیتا بیس بخونه و براساس اون یه فعالیتی انجام بده و بعد یه string یا integer برگردونه. از این متد هم در داخل یه بیزینس دیگه استفاده می شه.
همه میدونن که یک سلکت ممکنه دچار استثناء بشه (مثلا کانکشن استرینگ کلا غلط باشه) خب حالا ما تصمیم میگیریم سلکتمون رو داخل یه try بذاریم. خب تکلیف ادامه کار چیه؟ بهرحال متد ما نیاز به خروجی داره. بفرض اگر صفر یا null برگردونه خب ادامه بیزنس هم دچار مشکل میشه. این چرخه هندل کردن باید چطوری ادامه پیدا کنه؟آیا باید کل بیزینسمون رو داخل یه try بنویسیم؟!!! اینکه نه معقوله نه ممکن (البته ممکنه شما بگی معقول و ممکنه) از طرفی هندل کردنش باید چطوری باشه. فرض کن من تو قسمت catch اون باید چی بگم؟ بگم بیزینس قطع بشه و ادامه نده بقیش رو؟ با چه دستوری؟ بگم break کنه؟ خب اون میره ادامه کد رو از داخل بیزینس اجرا میکنه. بگه کلا هیچ اقدامی نکنه؟ یعنی بیا دستوراتم رو هم ولیدیت کنم که اگر هیچ استثنائی رخ ندا اجرا بشن؟
من مشکل عزیزی که تاپیک رو زده نمیدونم ولی خود بیسوادم دچار این مشکلاتم. حالا اگر بنظرتون کسی که میاد وقت میذاره و تاپیک میزنه و سوال مطرح میکنه میخواد که شما لینک msdn رو بهش بدید این دیگه زاویه دید شماست.

:متعجب:
با توجه به اینکه موضوع تایپیک یه چیزه دیگست ، بنده به شما پاسخی نمیدم ، شما اول جواب کلیت موضوع تایپیک رو بده بعد به جزئیات بپرداز .
در ضمن من برای شما آموزش سرچ گوگل نذاشتم و اگه شما نتونستی مطلبی از اون لینکا برداری بحثش جداست .
:خجالت: دوستان همگی ببخشید که بحث به جای دیگه کشیده شد :خجالت:
اما در مورد اینکه چه موقع باید از Exception Handling استفاده کرد ، باید بگم که :
در یک پروژه بزرگ معمولا طراح نرم افزار و یا برنامه نویس به صورت مستقیم با کاربران نهایی در ارتباط نیست ، و در نتیجه باید به گونه ای خطا ها رو مدیریت و یا Handle کرد که هر کدام از کسانی که با این پروژه کار می کنند از قبیل کاربر نهایی ، تیم پشتیبانی ، واحد تست و آزمایش نرم افزار با خطاهای معنا دار و مرتبط با خودشان مواجه شوند .
فرض کنید خطایی در لایه Data Access رخ داده و اگر قرار باشد خطای به وجود آمده به همه کاربران به یک شکل نمایش داده شود ، اطلاعات حساسی مثل Connection String در اختیار کاربران قرار می گیرد و این از لحاظ امنیتی اصلا خوب نیست . این تنها یک مثال است و موارد دیگری نیز هست که در یک پروژه بزرگ بسیار اتفاق می افتد و اگر قرار باشد همه ی خطاها به یک شکل برای کاربران ارسال شود که درست نیست .
امیدوارم که مطلب رو خوب رسونده باشم .
با تشکر . :لبخندساده:

علی متقی پور
دوشنبه 30 اردیبهشت 1392, 12:42 عصر
:متعجب:
با توجه به اینکه موضوع تایپیک یه چیزه دیگست ، بنده به شما پاسخی نمیدم ، شما اول جواب کلیت موضوع تایپیک رو بده بعد به جزئیات بپرداز .
در ضمن من برای شما آموزش سرچ گوگل نذاشتم و اگه شما نتونستی مطلبی از اون لینکا برداری بحثش جداست .
:خجالت: دوستان همگی ببخشید که بحث به جای دیگه کشیده شد :خجالت:
اما در مورد اینکه چه موقع باید از Exception Handling استفاده کرد ، باید بگم که :
در یک پروژه بزرگ معمولا طراح نرم افزار و یا برنامه نویس به صورت مستقیم با کاربران نهایی در ارتباط نیست ، و در نتیجه باید به گونه ای خطا ها رو مدیریت و یا Handle کرد که هر کدام از کسانی که با این پروژه کار می کنند از قبیل کاربر نهایی ، تیم پشتیبانی ، واحد تست و آزمایش نرم افزار با خطاهای معنا دار و مرتبط با خودشان مواجه شوند .
فرض کنید خطایی در لایه Data Access رخ داده و اگر قرار باشد خطای به وجود آمده به همه کاربران به یک شکل نمایش داده شود ، اطلاعات حساسی مثل Connection String در اختیار کاربران قرار می گیرد و این از لحاظ امنیتی اصلا خوب نیست . این تنها یک مثال است و موارد دیگری نیز هست که در یک پروژه بزرگ بسیار اتفاق می افتد و اگر قرار باشد همه ی خطاها به یک شکل برای کاربران ارسال شود که درست نیست .
امیدوارم که مطلب رو خوب رسونده باشم .
با تشکر . :لبخندساده:


داغونمون کردی با این همه اطلاعات نابی که دادی
هممون رو از گمراهی و ظلمت نجات دادی
مر30000000000000

FastCode
دوشنبه 30 اردیبهشت 1392, 14:28 عصر
از smiley متنفرم

علی متقی پور
دوشنبه 30 اردیبهشت 1392, 14:40 عصر
از smiley متنفرم

شما که کد میخواستی تا بتونی جواب بدی.
کد رو گرفتی و گفتی 60 تا ایراد داره.
الان این جوابتون بود؟