سلام به همه دوستان. من یه پیشنهاد دارم. با توجه به اهمیت برنامه نویسی شی گرا (چرا که به گفته یکی از اساتید برنامه نویس های شی گرا برنامه نویسای گرونی هستن)فکر می کنم
یاد گیری معماری چند لایه می تونه زمینه خوبی برای اون باشه.
ممکنه خیلی ها با این معماری آشنا باشن اما بعضی ها مثل من با اون کار نکرده باشن. پیشنهاد من اینه که اگر یکی از دوستان تو این زمینه تجربه ای داره لطف کنه
همکاری کنه یه برنامه ساده ارائه بده به صورت قدم به قدم(مثلا تو هر لایه) تا بقیه انجام بدن و اگه سوالی دارن همینجا مطرح کنن. به این شکل درک چگونگی لایه ها راحت تر میشه. حالا برای خالی نبودن عریضه یه توضیح اولیه و کلی گذاشتم.
تو معماری چند لایه کل برنامه به چندین بخش تقسیم می شه که این بخش ها می تونن فیزیکی یا منطقی باشن و هر بخش کار خاصی رو انجام می ده.تو معماری 3 لایه که متداوله برنامه ها سه لایه مجزا دارن که عبارتند از :
Presentation Layer لایه نمایش
BLL)Business Logic Layer) لایه منطقی یا تجاری
DAL)Data Access Layer ) لایه دسترسی به داده
لایه DAL داده های مورد نظر رو بازیابی می کنه و از طیق BLL اون ها رو به لایه نمایش می فرسته.و به عکس کاربر داده ها رو از طریق لایه نمایش تغییر می ده( مثل اضافه یا به روز کردن داده ها )و BLL داده ها رو اعتبار سنجی می کنه و اگر داده ها معتبر باشن اون ها رو به DAL می سپاره.
مزیت های این کار اینه که برنامه ها به چند بخش منطقی جدا از هم تقسیم می شن و اتصال بین لایه ها کم میشه و به این شکل تغییر در در هر لایه خللی به لایه های دیگه وارد نمی کنه و تغییر یا گسترش برنامه بدون نیاز به تغییر یا کامپایل مجدد برنامه کلاینت ساده تر میشه. همینطور اگه بخوایم یه برنامه تحت ویندوز رو به برنامه تحت وب تبدیل کنیم تنها لایه نمایش عوض میشه. یا اگه بخوایم دیتابیس رو از SQLServer ببریم روی Access یا برعکس، فقط لایه DAL عوض میشه. ضمن اینکه برنامه کلاینت نمی فهمه که داده ها از کجا اومدن (location transparency).
فایده دیگش اینه که تو کارهای تیمی، تیم ها یا افراد مستقل میتونن روی لایه های متفاوت به صورت موازی کار کنن بدون اینکه از لایه های دیگه اطلاع داشته باشن.
همینطور ازمهمترین مزیت هایی که لایه ای کردن پروژه میتونه داشته باشه افزایش امنیت داده های برنامه است.
اما نکته قابل توجه اینه که توی سیستم لایه بندی یه لایه نباید لایه بالای سر خودش رو صدا بزنه، همیشه ارتباط از بالا به پایینه و نه از پایین به بالا. مثلا BLL نمیتونه یه تابع از لایه نمایش رو فراخوانی کنه یا تغییری در اون ایجاد کنه .
یک مثال ساده از لایه دوم و سومتون بگم(لایه اول واضحه):
BLL: هسته برنامه رو شامل میشه(کدها ، کلاس ها و امکانات برنامه)
DAL: مربوط به وصل شدن به پایگاهتون، select ، insert و update و .... که میخواین روی دیتاهاتون انجام بدین
من خودم شخصا بصورت کامل این مبحث رو نخوندم و آشنایی ندارم باهاش اما یادم میاد تو برنامه نویس یه تاپیک خیلی کاملی در این زمینه بود و دوستانی که بخوبی تو این زمینه کار میکردن اونجا نظراتشون رو عنوان میکردن و توضیحاتی میدادن .
من چند تا مقاله در این رابطه بهتون میدم امیدوارم که بدردتون بخوره :
البته اینم عنوان کنم که مباحث شی گرایی رو اگر بخوبی پیاده اش کنید نهایتا به همین جداسازی کارها در لایه های مختلف میرسید . نمونه اش هم یک پروژه ای بود که من برای دانشگاه علوم و فنون مازندران نوشتم . که از سه بخش مختلف تشکیل شده بود .
1.بخش فرم ها و تشکیلات رابط کاربری
2.بخش clsWorker که وظیفه لایه منطقی رو بازی میکرد
و 3 بخش clsdb که درش کلاسها و متدهایی برای کار با دیتابیس وجود داشت .
+ کلاسهای دیگه ای (مثل Student, Employee ,...) که هر کدوم اعتبار سنجی های مورد نیازشون رو در خودشون داشتن که موقع استفاده دیگه نیازی به اعتبار سنجی چندگانه نباشه و...
بگزریم . فقط میخواستم بگم اگر شما همون اصل اول شی گرایی یعنی کپسوله سازی رو رعایت کنید 80 90 درصد راه رو رفتید و اون 10 20 درصد دیگه با مطالعه بیشتر و آشنایی با چنین مفاهیمی محقق میشه .
طبق درخواست شما آموزش مقدماتی از این بحث رو اینجا براتون قرار میدم . یک پروژه شروع میشه و لایه به لایه اون توضیح داده میشه :
برنامه نویسی چند لایه قسمت اول : مقدمه (n-tierd Programming)
خیلی از ما در مورد برنامه نویسی چند لایه بارها و بارها شنیده ایم ، بعضی از ما درست یا غلط از آن استفاده می کنیم و برخی هیچ گاه از آن استفاده نکرده ایم .
در این سری مقالات تلاش بنده این است که به صورت ملموس تجربیان شخصی خود را در مورد برنامه نویسی چند لایه در اختیار دوستان قرار دهم .
می دانم در ابتدای امر چندین سوال در ذهن شما مطرح شده است ، برای همین به برخی از مهمترین سوالات می پردازم :
منظور از لایه در برنامه نویسی چیست ؟
برای پاسخ به این سوال یک پروژه تحت وب را در نظر بگیرید ، در این پروژه شما قرار است یک عملیات بانک اطلاعاتی مانند درج و به روز رسانی و دریافت اطلاعات را انجام دهید ، شما میتوانید تمامی کد های مربوط به این عملیات را در یک صفحه (CodeBehind) بنویسید یا میتوانید این عملیات را به چند بخش تقسیم کرده و آنها را بر مبنای خاصی دسته بنده کنید ، این مبنا را لایه می نامیم .
حال سوال این است که مبنای دسته بندی چیست و این دسته بندی به چه صورت انجام میشود ؟
شما باید بدانید که یک روش ثابت برای دسته بندی وجود ندارد ولی برنامه نویسان و توسعه دهندگان طی تجربه به این نتیجه رسیده اند که یک پروژه را به سه یا چهار یا... لایه تقسیم کنند ، لایه اول Presention Layer یا User Interface نام دارد ، این لایه نهایی ترین لایه است و در دسترس کاربر نهایی قرار می گیرد ، کمترین کد در این لایه نوشته می شود (مثلا Default.aspx و Default.aspx.cs جزئی از این لایه هستند)
لابه دیگری به نام Data Access Layer (یا DAL) وجود دارد ، این لایه ارتباط با دیتابیس را برقرار می کند ، تمامی کد های مربوط به عملیات بانک اطلاعاتی (دریافت ، درج ، حذف و به روز رسانی و...) و کد های مربوط به ارتباط و قطع ارتباط در این لایه پیاده سازی می شود .
لایه ای به نام Bussiness Logic Layer نیز وجود دارد که بین DAL و UI قرار میگیرد ، این لایه وظایف متعددی را میتواند ایفا کند ، چک کردن شرط ها ، برخی اعتبار سنجی ها ، فراخوانی متدهای DAL و همچنین OR Mapping (مپ کردن فیلدهای بانک اطلاعاتی به کلاس) و .... از را می توان از وظایف این لایه نام برد .
لایه دیگری نیز میتوان به لایه های فوق اضافه کرد ، Cache Layer لایه ذخیره اطلاعات در حافظه کش است ، همانطور که میدانید کش از حافظه کوتاه مدت استفاده می کند بنابراین بسیار سریعتر از دیتابیس( که بر روی هارد دیسک ذخیره می شود ) قابل دسترسی است . برخی اطلاعات پر استفاده که نیازی ندارد به روز باشند را میتوان در کش ذخیره کرد . این لایه بین BLL و UI قرار میگرد تا UI به جای استفاده از اطلاعات تازه از کش اطلاعات را واکشی نماید .
میتوان لایه های دیگری را نیز بر حسب نیاز اضافه کرد و یا از برخی لایه های فوق استفاده نکرد ، هیچ الزامی وجود ندارد .
برخی از افراد خود دیتابیس را هم یک لایه در نظر میگیرند و برخی خیر ، بنابراین اگر اسمی از برنامه نویسی سه لایه یا چهارلایه یا پنج لایه به گوش شما خورد بدانید که به کمی توضیح بیشتر نیاز دارد
معمول ترین روش برنامه نویسی چند لایه برنامه نویسی سه لایه ( 3tierd ) است » UI , BLL , DAL
چه نیازی به لایه بندی پروژه است ؟
شرکتی را در نظر بگیرید که 40 کارمند دارد ، این شرکت میتواند یک آپاراتمان 200 متری را اجاره کرده و تمام کارمندان خود را در این واحد مستقر کند . با این کار همه کارمندان واحد های مختلف (بازرگانی ، اداری ، مالی ، فنی و...) در کنار هم خواهند بود ، هم همه ، ازدحام رفت و آمد مشتری و.... از ابتدایی ترین مشکلات این روش خواهد بود .
اما این شرکت میتواند 3 طبقه 80 متری تهیه کند و واحد های مختلف را در طبقات مختلف مستقر نماید ، با این کار شاید شرکت هزینه بیشتری را متقبل شود و دسترسی واحد ها به یکدیگر به سادگی قبل نباشد ولی در عوض آرامش ، افزایش بازدهی کار ، برقرار شدن نظم و سکوت ، رضایت مشتری و.... از نتایج آن خواهد بود .
کد نویسی هم از این قاعده مستثنی نیست ، در حقیقت با این کار هر قطعه کد در سر جای خود قرار می گیرد .
علاوه بر نظم دهی به کد نویسی و خوانا شدن کد ، روش های چند لایه مزایای دیگری نیز دارند :
هر لایه در نهایت به Dll تبدیل شده و مجزا می شود بنابراین قابلیت استفاده از هر لایه در پروژهای مختلف یا حتی چند پروژه در آن واحد (مثلا پنل مدیریت و نمایه یک وب سایت به صورت اشتراکی از لایه BLL و DAL استفاده می کنند ) را در اختیار توسعه دهنده قرار می دهد .
جداشدن لایه ها و تمیز شدن کد ها به تیم برنامه نویس کمک می کند که بتوانند در کنار هم راحت تر کار کنند
در هنگام تغییر بانک اطلاعاتی کل پروژه تحت الشعاع قرار نمی گیرد و تغییرات فقط در لایه ارتباط با بانک اطلاعاتی اعمال می شود .
روند خطا یابی (Debuging) تسهیل می گردد
برنامه نویسی شی گرا OOP در روش چند لایه نمود پیدا کرده و قابل پیاده سازی می گردد
از تکرار کد در صفحات مختلف جلوگیری می شود .
کامپایل شدن و بارگذاری پروژه بسیار ساده تر خواهد شد .
احتمال بروز خطای انسانی در هنگامی کد نویسی به حداقل کاهش می یابد .
و...
لایه بندی پروژه در سرعت توسعه پروژه و همچنین سرعت لود شدن صفحات چه تاثیری دارد ؟
در هنگام لایه بندی پروژه به ویژه در دفعات اول به نظر می رسد که از سرعت توسعه و پیشرفت پروژه کاسته می شود ولی واقعیت این است که این کار با نظم دهی در کار ها و سهولت خطا زدایی سرعت شما را موارد بسیاری افزایش خواهد داد .
میتوان گفت تاثیری خاصی در بارگذاری صفحات ندارد مگر اینکه از لایه CL یا Cache Layer استفاده کنید که این کار مسلما باعث افزایش سرعت و بازدهی پروژه شما خواهد شد .
برنامه نویسی چند لایه قسمت دوم : لایه ارتباط با پایگاه داده (Data Access Layer یا DAL)
برنامه نویسی چند لایه قسمت دوم : لایه ارتباط با پایگاه داده (Data Access Layer یا DAL) :
در قست اول مقاله (مقدمه برنامه نویسی چند لایه) در مورد لایه بندی پروژه و مزایای استفاده از معماری چند لایه صحبت شد ، در این مقاله تئوری های گفته شده را عملی خواهیم کرد .
برای شروع برای اینکه یک پروژه تمیز داشته باشیم قدم به قدم به صورت زیر عمل نمایید :
نرم افزار ویژوال استودیو را باز نمایید ، وارد منوی File و سپس New Project شوید
از لیست سمت چپ (Project Types) گزینه Other Project Types و سپس Visual Studio Solution را برگزینید
از لیست سمت راست (Templates) گزینه Blank Solution را انتخاب نمایید
یک نام برای Solution خود در قسمت Name وارد نمایید
مسیر Location را به دایرکتوری مجازی خود تغییر دهید (مثلا C:\Intepub\wwwroot ) و تایید نمایید
اکنون شما یک Solution خالی در مسیر دایرکتوری مجازی IIS ایجاد کرده اید ، ما در این پروژه خالی لایه ها را ایجاد خواهیم کرد ، هر یک از لایه ها به صورت یک پروژه جداگانه از نوع Class Library خواهند بود .
برای ایجاد یک لایه جدید به صورت زیر عمل نمایید :
وارد منوی File > Add > Add New Project شده
از سمت چپ زبان مورد نظر خودتان را انتخاب نمایید (Visual C Sharp یا Visual Basic)
از سمت راست گزیته Class Library را انتخاب نمایید
در فیلد Name نام لایه را تایپ نموده (در اینجا نام DAL را برای لایه ارتباط با دیتابیس وارد می کنید) و تایید نمایید
برای اضافه نمودن لایه Bussiness Logic هم دقیقا روال فوق را طی کرده و نام BLL را وارد می نماییم .
برای ایجاد لایه User Interface یا UI به دلیل اینکه وب سایت ما را تشکیل می دهد بایک یک پروژه از نوع WebSite اضافه نماییم ، بنابراین وارد منوی File>Add >Add New Website شده ، مسیر Location را بر اساس پروژه ایجاد شده وارد نمایید (مثلا http://localhost/3-tier ) این کار باعث می شود که هم دایرکتوری مجازی ایجاد شود و هم اینکه لایه مورد نظر داخل پروژه قرار گیرد .
اگر از IIS استفاده نمی کنید کافیست مسیر را به صورت فیزیکی ست نمایید : C:\Inetpub\wwwroot\3-tier
تا اینجای کار ما 3 لایه ای که مد نظرمان بود را اضافه کردیم ، اکنون به سراغ لایه DAL می رویم .
به صورت پیشفرض یک کلاس به نام Class1 داخل این پروژه وجود دارد ، آن را حذف نمایید .
همانطور که در مقاله قبلی توضیح دادم این لایه تمام عملیات مربوط به بانک اطلاعاتی را انجام می دهد ، معمولا ما برای هر جدول از دیتابیس یک کلاس در این لایه ایجاد می کنیم ، اگر جدول های شما ارتباط تنگانگی باهم دارند میتوانید برای یک مجموعه از جداول یک کلاس در نظر بگیرید .
به عنوان مثال اگر یک جدول برای ذخیره نام کشور ها و یک جدول برای نام شهر ها دارید میتوانید آن ها را در یک کلاس قرار دهید ولی اگر یک جدول برای ذخیره کاربران و یک جدول برای مقالاتی که کاربران ارسال کرده اند دارید هر یک از این جداول را با یک کلاس Map می کنیم .
قبل از اینکه به سراغ ساخت کلاس ها برویم ، یک کلاس مادر ایجاد می کنیم که برخی از متدها و خواص عمومی را برای ما انجام می دهد ، بنابراین در لایه DAL گزینه Add New Item را از منوی Project انتخاب کرده و یک Class با نام DALBase.cs اضافه نمایید :
اگر کلاس شما از نوع Public نبود کلمه Public را به قبل نام class اضافه نمایید :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DAL
{
public class DALBase
{
}
}
این کلاس میتواند شامل رشته اتصال و همچنین مجموعه ای از توابع و متدها برای کار با بانک اطلاعاتی باشد (به عنوان مثال متد ExecuteNoneQuery را در کلاس زیر پیاده سازی کرده ایم ، بقیه متد ها در فایل ضمیمه موجود می باشد) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace DAL
{
public class DALBase
{
public string ConnectionString
{
get
{
return "Data Source=.;Initial Catalog=Db;Integrated Security=True";
}
}
public int ExecuteNoneQuery(CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
using (SqlConnection con = new SqlConnection(ConnectionString))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = commandType;
cmd.CommandText = commandText;
cmd.Parameters.AddRange(commandParameters);
con.Open();
int retVal = cmd.ExecuteNonQuery();
con.Close();
return retVal;
}
}
}
}
همچنین میتوانید رشته اتصال را از App.Config هم فراخوانی نمایید (در فایل ضمیمه این کار در App.Config انجام شده است) .
البته شما میتوانید از Microsoft Application Block یا Microsoft Enterprise Library برای این کار استفاده کنید .
برای استفاده از این کتابخانه ها ابتدا این کتابخانه را از اینجا دانلود کرده و سپس توسط Add Refrence به پروژه اضافه کنید ، و به جای متدهایی که خودتان می نویسید از این کتابخانه استفاده نمایید .
برای شروع کار یک دیتابیس ایجاد کرده و جدولی برای ذخیره اطلاعات کاربران در آن قرار دهید :
اکنون میخواهیم کلاس مربوط به این جدول را در لایه DAL ایجاد کنیم ، بدین منظور در پروژه مربوط به لایه DAL وارد Add new item شده و یک آیتم از نوع Class با نام Users.cs اضافه نمایید ، کلاسی شبیه کلاس زیر ایجاد خواهد شد :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DAL
{
class Users
{
}
}
قبل از هر چیز این کلاس را Public نموده و سپس از کلاس مادر ارث بری می کنیم :
public class Users : DALBase
{
}
اکنون متد های مورد نیاز را ایجاد می کنیم ، به عنوان مثال متد Insert :
public int AddNewUser(string firstName, string lastName, string emailAddress, string username, string password, byte userStatus)
{
return ExecuteNoneQuery(System.Data.CommandType.StoredProcedure, "AddNewUser", new SqlParameter[] {
new SqlParameter("@firstName", firstName),
new SqlParameter("@lastName", lastName),
new SqlParameter("@emailAddress",emailAddress),
new SqlParameter("@password",password),
new SqlParameter("@userStatus",userStatus),
});
}
و متدی برای دریافت اطلاعات :
public SqlDataReader GetUserByUserID(int userId)
{
return ExecuteReader(System.Data.CommandType.StoredProcedure, "GetUserByUserID", new SqlParameter[] {
new SqlParameter("@userId", userId),
});
}
و متدهای دیگری که باید پیاده سازی شود (مانند حذف و به روز رسانی و ....)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
namespace DAL
{
public class Users : DALBase
{
public int AddNewUser(string firstName, string lastName, string emailAddress, string username, string password, byte userStatus)
{
return ExecuteNoneQuery(System.Data.CommandType.StoredProcedure, "AddNewUser", new SqlParameter[] {
new SqlParameter("@firstName", firstName),
new SqlParameter("@lastName", lastName),
new SqlParameter("@emailAddress",emailAddress),
new SqlParameter("@password",password),
new SqlParameter("@userStatus",userStatus),
});
}
public SqlDataReader GetUserByUserID(int userId)
{
return ExecuteReader(System.Data.CommandType.StoredProcedure, "GetUserByUserID", new SqlParameter[] {
برنامه نویسی چند لایه قسمت سوم : لایه منطق تجاری (BLL یا Bussiness Logic Layer)
در قسمت های قبلی مقاله با برنامه نویسی چند لایه و ضرورت لایه بندی آشنا شدیم و لایه ارتباط با پایگاه داده را پیاده سازی کردیم ، در این مقاله به ایجاد و پیاده سازی لایه BLL می پردازیم .
قبل از هر چیز یک پروژه دیگر به نام BLL پروژه اصلی اضافه نمایید ، روند کار دقیقا شبیه لایه قبلی است ، یک کلاس به نام Users به این پروژه اضافه نمایید .
اکنون وارد منوی Project>Addrefrence شده و از تب Project گزینه DAL را انتخاب کنید ، این کار باعث میشود مرجع لایه DAL به پروژه شما اضافه شود و شما به کدهای نوشتی شده در این لایه دسترسی پیدا کنید .
شاید در وحله اول به نظر برسد که نیازی به چنین لایه ای نیست ، در اصل این لایه چند وظیفه عمده بر عهده دارد :
واسط بین لایه DAL و UI است و باعث مرتب شدن و دسته بندی کد های می گردد
عملیات اعتبار سنجی مقادیر را بر عهده دارد تا مطمئن شویم اطلاعاتی که به دیتابیس ارسال می شوند از هر نظر بدون نقص هستند
فیلد های دیتابیس را در کلاس شبیه سازی می کند (ORMapping) تا در متدهای Select استفاده شود
در این لایه به ازای هر جدول در دیتابیس یک کلاس ایجاد خواهد شد ، تمام فیلد های جدول دیتابیس به صورت Property در کلاس پیاده سازی می شوند (به مقاله اصول شی گرایی (OOP) قسمت سوم : خواص مراجعه شود) و سپس متد های مورد نیاز ایجاد شده و متد های منتاظر در لایه DAL را فراخوانی می کنند . به عنوان مثال جدول کابران در مقاله قبل را در نظر بگیرید :
اکنون ما فیلدهای این جدول را در کلاس Users در لایه BLL به صورت Property پیاده سازی می کنیم :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BLL
{
public class Users
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public byte UserStatus { get; set; }
}
}
دقت نمایید که بنده Property ها را به صورت Auto Property و به صورت خلاصه تعریف کردم اگر از ورژن های پایین تر از Dotnet Framwork 3.5 استفاده می کنید لازم است که آنها را به صورت کامل تعریف کنید ، مثلا :
private int _UserID;
public int UserID
{
get
{
return _UserID;
}
set
{
_UserID = value;
}
}
اکنون که فیلد ها ایجاد شدند به سراغ پیاده سازی متد ها می رویم ، و متد AddNewUser را پیاده سازی می کنیم .
همانطور که در ابتدا گفته شد در این لایه انواع اعتبار سنجی های مورد نیاز انجام خواهد شد ، برای روشن شدن مطلب فرض کنید متد AddNewUser برای ثبت نام افراد استفاده می شود بنابراین ایمیل کاربر باید از نظر تکراری بودن چک شود ، بنابراین قبل از فراخوانی متد AddNewUser در لایه Dal باید اطلاعات به اشکال مختلف اعتبار سنجی شوند .
فرض کنید متد زیر را در لایه DAL نوشته ایم :
public int GetUserCountByEmail(string emailAddress)
{
object retVal = ExecuteScaler(System.Data.CommandType.StoredProcedure, "GetUserCountByEmailAddress", new SqlParameter[] {
new SqlParameter("@emailAddress",emailAddress)
});
if (retVal != null)
return Convert.ToInt32(retVal);
else
return 0;
}
همچنین مشابه این متد را برای چک کردن Username نیز به لایه DAL اضافه می نماییم .
اکنون در لایه BLL متد AddNewUser را به صورت زیر می نویسیم :
public static int AddNewUser(string firstname, string lastname, string emailAddress, string userName, string password, byte userStatus)
{
DAL.Users users = new DAL.Users();
int retval = 0;
if (users.GetUserCountByEmail(emailAddress) != 0)
{
retval = 1; // ایمیل قبلا ثبت شده است
}
if (retval == 0 && users.GetUserCountByUsername(userName) != 0)
{
retval = 2; // نام کاربری قبلا ثبت شده است
}
همانطور که ملاحظه می کنید در این متد ابتدا صحت ایمیل بررسی شده و اگر ایمیل قبلا ثبت شده باشد مقدار متغیر retval برابر 1 قرار میگیرد ، در مرحله دوم اگر ایمیل آزاد بود نام کابری چک می شود و در نهایت اگر هیچ مشکلی وجود نداشت کاربر ثبت می گردد .
و از این قبیل اعتبار سنجی ها که باعث می شود اطلاعات ارسالی به دیتابیس از هر نظر تمیز باشد ، البته خیلی اعمال دیگر را هم میتوان در این لایه انجام داد که به مرور زمان با آن مواجه خواهید شد .
اکنون متد GetUsers را برای دریافت لیست کلیه کاربران به صورت زیر پیاده سازی می کنیم ، دقت بفرمایید که متد مورد نیاز (GetUsers) قبلا باید در لایه DAL نوشته شده باشد :
public static List<Users> GetUsers()
{
DAL.Users users = new DAL.Users();
IDataReader dr = users.GetUsers();
همانطور که ملاحظه می کنید ابتدا اطلاعات توسط متد GetUsers که در لایه DAL نوشته شده بود داخل یک IDataReader ریخته می شوند (دلیل انتخاب IDataReader به جای SQLDataReader حفظ استقلال این لایه از نوع بانک اطلاعاتی بوده است ، در ضمن فضا نام System.Data باید اضافه گردد ) ، در مرحله بعد یک لیست Generic از همین کلاس Users به نام userList ایجاد می گردد (متغیر های Generic به شما این امکان را می دهند که نوع داده را از نوع یک کلاس تعریف نمایید) ، سپس وارد حلقه خواندن اطلاعات می شویم ، در این حلقه یک شی جدید از همین کلاس ایجاد شده Property ها مقدار دهی می شوند و سپس این شی به لیست Generic اضافه می شوند و در نهایت این لیست از تابع Return می شوند .
با اینکار هم استقلال کلاس از نوع بانک اطلاعاتی حفظ شده و هم در لایه UI که لایه نهایی ما است هیچ نیازی به لایه DAL نخواهد بود و این یکی از اهداف لایه بندی پروژه است .
کار تقریبا تمام است ، اکنون وارد لایه UI که در مقاله قبل ایجاد کرده بودید بشوید و سپس از طریق گزینه Add Refrence و با استفاده از تب Projects لایه BLL را به این لایه اضافه نمایید .
اکنون میتوانید خیلی ساده از متدهایی که نوشتید استفاده کنید ، به عنوان مثال برای نمایش اطلاعات در یک GridView داریم :
int retval = BLL.Users.AddNewUser("ali", "delshad", "ali@how2learnasp.net", "ali", "123");
switch (retval)
{
case 1:
Response.Write("ایمیل تکراری است");
break;
case 2:
Response.Write("نام کاربری");
break;
case 0:
Response.Write("کاربر با موفقیت ثبت شد");
break;
}
البته روشی که در بالا برای واکشی اطلاعات استفاده کردیم یک List از کلاس Users را بر میگرداند که مناسب بایند کردن در یک کنترل قابل بایند مانند Gridview یا DropDownList بود ، اگر ما بخواهیم این اطلاعات را در یک فرم نمایش دهیم دیگر نیازی به یک List از کلاس نخواهیم داشت بلکه فقط یک شی از آن کلاس مورد نیاز خواهد بود ، فرض کنید بخواهید اطلاعات یک کاربر را دریافت و آن را در یک فرم نمایش دهیم (مثلا برای ویرایش ) برای این منظور ابتدا یک متد دیگر به شکل زیر ایجاد می نماییم :
public static Users GetUserByUserID(int userId)
{
DAL.Users users = new DAL.Users();
IDataReader dr = users.GetUserByUserID(userId);
و برای استفاده از آن به سادگی داریم (فرض کنیم بخواهیم یک کاربر با کد 1 را درخواست کنیم ، البته شما میتوانید این کد را از QueryString یا هر جای دیگر به صورت پارامتریک دریافت نمایید ):
نکته دیگری که باید به آن توجه کنید این است که اگر رشته اتصال خود را در لایه DAL داخل وب کانفیگ قرار داده اید باید داخل لایه UI آن را دوباره بنویسید ، در پروژه بنده این رشته در AppSettings لایه DAL نوشته شده و در لایه UI در فایل Web.Config به صورت زیر Override شده است :
در قسمت بعدی مقاله با Cache Layer (لایه کش) آشنا خواهیم شد که به افزایش سرعت بارگزاری و کاهش ترافیک دیتابیس کمک شایانی خواهد کرد .
برنامه نویسی چند لایه قسمت چهارم : لایه کش (CL یا Cache Layer)
در مقالات قبلی با ضرورت لایه بندی پروژه ، لایه ارتباط با بانک اطلاعاتی و لایه منطق تجاری و لایه واسط کاربر آشنا شدیم ، در این مقاله قصد دارم یک لایه جدید به پروژه اضافه کنم ، این لایه به افزایش سرعت لود اطلاعات و همچنین بهبود در کارایی سیستم و کاهش فشار بر روی بانک اطلاعاتی کمک زیادی خواهد کرد .
این لایه Cache Layer یا لایه کش نام دارد ، همانطور که میدانید Cache بر خلاف دیتابیس اطلاعات (که اطلاعات را در هارد دیسک ذخیره می کند) را در حافظه جانبی (RAM) ذخیره می کند بنابراین سرعت دسترسی و خواندن و نوشتن اطلاعات بسیار بالا خواهد بود ، بنابراین مکان مناسبی برای ذخیره اطلاعاتی است که به کرات درخواست می شود و به ندرت به روز می گردد .
این لایه حد فاصل لایه BLL و UI قرار میگیرد و باعث می گردد به جای اینکه اطلاعات به صورت مستقیم از دیتابیس درخواست داده شود از کش خوانده شود .
برای شروع کار ابتدا یک پروژه جدید از نوع Class Library به نام CL به Solution اضافه کنید (طبق روال قبل) ، قبل از هر چیز پروژه BLL را در این پروژه Add Refrence نمایید ، سپس یک کلاس به نام CLBase به این پروژه اضافه کنید ، این کلاس شامل Property ها و متدهایی است که در تمام کلاس ها استفاده می شود (مانند کلاس مادر در لایه DAL) .
همانطور که میدانید کلاس Cache در فضا نام System.Web قرار دارد بنابراین باید این فضا نام را به پروژه اضافه کنیم ، برای اینکار وارد منوی Project>Add Refrence شده از تب اول (NET.) فضا نام System.Web را انتخاب کرده و تایید نمایید .
// Make sure MasterCacheKeyArray[0] is in the cache - if not, add it
if (DataCache[MasterCacheKey] == null)
DataCache[MasterCacheKey] = DateTime.Now;
// Add a CacheDependency
System.Web.Caching.CacheDependency dependency = new System.Web.Caching.CacheDependency(null, new string[] { MasterCacheKey });
DataCache.Insert(GetCacheKey(rawKey), value, dependency, DateTime.Now.AddMinutes(CacheDuration), System.Web.Caching.Cache.NoSlidingExpiration);
}
public void InvalidateCache()
{
// Remove the cache dependency
HttpRuntime.Cache.Remove(MasterCacheKey);
}
}
}
متد اول بسیار سادست ، تنها کاری که میکند این است که نام کلید اصلی کلاس کش را به نام کش مربوط الصاق می کند ، این کار برای جلوگیری از تکرار در نام کش ها است .
متد دوم با دریافت نام Cache آن را از حافظه واکشی می کند و متد سوم وظیفه درج یک آیتم جدید در کش را بر عهده دارد و متد چهارم کش را ریست می نماید .
اکنون که کلاس مادر حاضر شده است به سراغ یکی از کلاس Users رفته و آن را پیاده سازی می کنیم ، برای این کار یک کلاس جدید به نام UsersCL یا Users به این پروژه اضافه کنید ، و آنرا از کلاس مادر یعنی CLBase مشتق نمایید . در سازنده کلاس (Constructor) دو خاصیت MasterCacheKey و CacheDuration را مقدار دهی می کنیم و سپس متد GetUsersByUserID را در لایه کش پیاده سازی می نماییم :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CL
{
public class Users : CLBase
{
public Users()
{
CacheDuration = 60.0;
MasterCacheKey = "UsersCache";
}
public List<BLL.Users> GetUserByUserID(int userId)
{
string rawKey = string.Concat("UserByUserID-", userId);
List<BLL.Users> UserData = GetCacheItem(rawKey) as List<BLL.Users>;
همانطور که ملاحظه می کنید ابتدا یک نام برای کش درنظر گرفته شده است ، این نام ترکیبی از کلمه UserByUserID و کد کاربری است بنابراین به ازای هر کاربر یک کش در حافظه ذخیره می شود (البته معمولا در این گونه موارد از کش استفاده نمی شود و این جا فقط جنبه آموزشی دارد)
سپس توسط متد GetCacheItem که در کلاس مادر نوشتیم مقدار کش واکشی شده و در یک شی از نوع لیست کلاس BLL.Users ریخته می شود ، واضح است که بار اول که این متد فراخوانی می شود مقدار بازگشتی Null خواهد بود چرا که کشی در کار نیست !
سپس در صورت Null بودن این مقدار اطلاعات از طریق لایه BLL از دیتابیس واکشی شده و توسط متد AddCacheItem در کش ذخیره می شود ، بدیهی است دفعه آتی شرط برقرار نخواهد شد و اطلاعات به جای اینکه از دیتابیس واکشی شود از کش درخواست می گردد .
کار تقریبا تمام است ، برای تست میتوانید در لایه UI ابتدا پروژه CL را AddRefrence کرده و سپس به صورت زیر عمل نمایید :
CL.Users UserFromCache = new CL.Users();
GridView2.DataSource = UserFromCache.GetUserByUserID(-1);
GridView2.DataBind();
بنده دو Girdview در صفحه قرار دادم ، یکی از لایه BLL و دیگری از CL بایند می شوند ، بار اول اطلاعات هر دو جدول یکسان بود :
برای ریست کردن کش هم خیلی ساده میتوانید از متد زیر استفاده کنید :
CL.Users UserFromCache = new CL.Users();
UserFromCache.InvalidateCache();
نکته لازم به ذکر این است که این استفاده از این لایه کاملا اختیاری است ، این لایه نیاز به دقت بیشتری نسبت به لایه های دیگر داشته و هرگونه اشتباه در استفاده از آن باعث بروز مشکلات فراوانی در پروژه شما خواهد شد و بالعکس استفاده با دقت و هوشمندانه سایت شما را در سطح بسیار بالایی بهینه خواهد کرد .
در آخر این لینک هم ببینید بد نیست : برنامه چند لایه چیست؟ ( هرچند به تفصیل مقاله هایی که ضمیمه کردم این موضوع رو توضیح دادن اما این هم بخاطر مختصر بودن خوبه ) .
به نام خدا
مبحث معماری چند لایه میشه گفت یکی از پر کاربردترین استفاده هاش تخصیص و تفکیک وظایف در کار تیمی روی پروژه باشه یکی از بهترین معماری ها ، معماری MVC
(Model–view–controller) هست :
model : از 2 زیر لایه اصلی و یک فرعی تشکیل شده --> BL , DAO ,DTO
data access object : وظیفه ارتباط با پایگاه را دارد
data table object : این قسمت اختیاری هستش و وقتی که به طور مثال یک select روی DB زده میشه حاصل باید رویproperty های یک class بشینه و این کلاس به BL فرستاده بشه ( منطق ORM در ORDBMS)
bl : وظیفه ارتباط با لایه controller را دارد تا متد های dao را فرا خوانی کند و یا مالیات را بر روی مقدار ورودی اعمال و بعد به dao برود
controller : سه وظیفه اصلی دارد :
1- mapping : انتقال کاربر ما بین صفحات یا frame ها
2- validation : اعتبار سنجی
3- bl connection: ارتباط با bl و فراخوانی متد مد نظر برای ارتباط با dao
view : هر آنچه که کاربر میبیند .
در آخر هم باید بگم که اینها تجربیات شخصی من از MVC هست و ممکن اشتباهاتی در اون باشه که ازین بابت از اساتید گرامی پوزش میطلبم
علاقه مندی ها (Bookmarks)