check home phone-call search send

آموزش مفاهیم معاری چند لایه، معماری 3- لایه، معماری n-layer – قسمت اول

 آموزش مفاهیم معاری چند لایه

توسعه دهندگان نرم افزار اغلب برای کسب بیشتر موارد کیفیت سرویس(Quality of Services)تصمیم به انتخاب یا تغییر معماری موجود می گیرند. برخی از موارد QoS عبارتند از:

  • قابلیت پایداری – Stability
  • قابلیت توسعه پذیری – Scalability
  • قابلیت دسترسی پذیری – Accessibility
  • قابلیت حمل – Portability
  • قابلیت برنامه نویسی – Programmability
  • قابلیت تست – Testability
  • قابلیت استفاده مجدد – Reusability
  • کارائی – Performance
  • امنیت – Security

برای معماری نرم افزار تعاریف مختلفی وجود دارد. از نظر آقای Martin Fowler معماری نرم افزار عبارتست از سازماندهی اساسی از مؤلفه های نرم افزاری و دو قانون مهم :

  • قوانین حاکم بر توسعۀ مؤلفه های نرم افزاری
  • قوانین حاکم بر ارتباط مؤلفه ها با هم و مؤلفه ها با محیط

یکی از انواع معماری های موجود، معماری n-لایه یا n-Layer می باشد که در آن n معمولاً 3، 5 و یا 7(به ندرت) می باشد. در معماری n-لایه تمامی بخش های نرم افزار به n لایه تقسیم می شود و اساس این تقسیم بندی این است که  تمامی کارهای مرتبط با هم (من جمله کارهای ارتباط با کاربر، هوش اصلی برنامه یا همان بخش محاسبات، کارهای مربوط به کار با داده ها) در لایه های مجزا قرار گیرد.

لازم به ذکر است که در برخی منابع از واژه n-Tier به جای n-Layer استفاده می شود و اغلب فکر می کنند که بین این دو واژه تفاوتی وجود ندارد، در صورتی که این تفکر اشتباه است.

Tier اشاره به اجزای فیزیکی نرم افزار دارد. یعنی اجزا می توانند به لحاظ فیزیکی روی چند ماشین به صورت جدا از هم قرار بگیرند و یا اگر در یک ماشین قرار دارند تخصیص حافظه به آنها کاملا جدا و مستقل از هم است. امّا واژه Layer به تقسیم بندی مجازی  اجزاء اشاره دارد و این یعنی اینکه یک Tier خود بصورت داخلی می تواند Layer بندی شده باشد. برای درک بهتر موضوع، Tierها شبیه به اسمبلی های تولید شده در .Net می باشند، یعنی همان فایل های .exe یا .dll، امّا Layer ها مانند فضاهای نام) (namespace ها می باشند که وظیفه آنها تنها قسمت بندی مجازی اجزای داخلی برنامه می باشد.

معماری 3-لایه، معماری n-لایه، معماری n-tier

در این مقاله ما به شرح معماری 3-Layer می پردازیم. در معماری 3-لایه تمامی قسمت های برنامه به 3 لایه اصلی تقسیم می شوند که عبارتند از:

لازم به ذکر است که اساس لایه بندی باید به گونه ای باشد که لایه ها تا حد امکان مستقل از یکدیگر باشند. به عبارتی دیگر لایه ها باید بیشترین پیوستگی درونی و کمترین وابستگی بیرونی را داشته باشند. همچنین هر لایه درخواست هایی را از لایه بالاتر می گیرد و نتایج را به آن لایه تحویل می دهد.

آموزش مفاهیم معماری 3-لایه، معماری n-Layer، معماری n-tier

در ادامه همراه با توسعه یک پروژه بسیار ساده به شرح هر یک از لایه ها می پردازیم.

1. لایه واسط کاربر – UIL

تمامی عملیات مربوط به ارتباط مستقیم با کاربر در این لایه قرار می گیرد. به عبارت دیگر این لایه واسط بین کاربر و دیگر لایه ها می باشد.

این لایه خود به دو قسمت تبدبل می شود.

الف)  UI Controls

در این قسمت تمامی اجزای ویژوال برنامه قرار می گیرند. یعنی تنها قسمت هایی از برنامه که کاربر آنها را مشاهده می کند، همانند کنترل های قرار  گرفته روی فرم برنامه. برای مثال در برنامه Visual Studio هر کلاس فرم به دو قسمت شکسته می شود.

Form.cs  و Form.Designer.cs که در قسمت Form.Designer.cs تنها تعاریف مربوط به کنترل های قرار گرفته روی فرم و تعیین خصوصیان آنها قرار می گیرد.

آموزش معماری 3 - لایه، معماری چند لایه توسط سورس ایران
مفاهیم معماری چند لایه

 ب)  UI Components

متدها و رویدادهایی که دستورات را از کاربر گرفته و به دیگر لایه ها ارسال می کنند در این لایه قرار می گیرند. برای مثال در VS تمامی رویدادها و متدهای تعریف شده در یک فرم در کلاس Form.cs قرار می گیرند. گفتنی است که این دو قسمت در این لایه بصورت کاملاً جدا از هم نیستند، مثلاً اگر با دقت به یک کلاس فرم در VS نگاه کنید، این دو کلاس در اصل یکی هستند چرا که با کلمه کلیدی partial تعریف شده اند.

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

در این مرحله به سراغ کد نویسی و توسعه پروژه می رویم. برای شروع کار یک پروژه ویندوزی مبتنی بر فرم را در Visual Studio ایجاد کنید. در مرحله بعد در Solution Explorer (کلید میانبر Ctrl+W+S) بر روی پروژه راست کلیک کرده و در منوی Add گزینه New Folder را انتخاب کنید و عنوان UIL را برای این پوشه جدید وارد کنید. سپس فرم پیش فرضی که Visual Studio با نام Form1 ساخته را با ماوس به داخل این پوشه Drag کنید و سپس بر روی فرم کلیک راست کرده و گزینه Rename را انتخاب نمایید و سپس عنوان MainForm را برگزینید. این فرم، فرم اصلی برنامه خواهد بود و نقطه اصلی دسترسی به سایر فرم ها می باشد. سپس بر روی پوشه UIL کلیک راست کرده و یک پوشه جدید با نام MemberForms را به این پوشه اضافه کنید. سپس بر روی این پوشه کلیک راست کرده و در زیر منوی Add یک فرم ویندوزی جدید با نام AddNewMembersForm را به این پوشه اضافه کنید. در این مرحله ساختار پروژه شما باید به شکل زیر باشد.

آموزش مفاهیم معماری چند لایه، معماری n- لایه، معماری n-layer
مفاهیم معماری چند لایه توسط سایت سورس ایران

تا این مرحله توانستیم که با کمک همدیگر لایه واسط کاربری برنامه یا همان User Interface Layer را بسازیم.

در این مرحله به سراغ طراحی ویژوال فرم ها می پردازیم. ابتدا در Solution Explorer بر روی MainForm دابل کلیک کرده تا محیط طراحی آن باز شود. در پنجره Toolbox (کلید میانبر Ctrl+W+X) یک کنترل Button را بر روی فرم دراگ کنید و در پنجره Properties (کلید میانبر Ctrl+W+P) خاصیت Name آنرا به btnAddNewMember و خاصیت Text آنرا به “عضو جدید” تغییر دهید. بر روی این دکمه دابل کلیک کنید تا به محیط کد نویسی منتقل شوید. در رویداد کلیک ایجاد شده کدهای زیر را برای نمایش فرم AddNewMemberForm را اضافه نمایید.

AddNewMemberForm frmNewUser = new AddNewMemberForm();
frmNewUser.ShowDialog(this);

فقط در ابتدا فضای نام پوشه صاحب این فرم یعنی SourceIran_n_Layer_Library.UIL.MembersForm را using کنید. فرم AddNewMemeber را بصورت زیر طراحی کنید.

آموزش مفاهیم معماری 3 - لایه توسط سایت سورس ایران
آموزش مفاهیم معماری 3 – لایه توسط سایت سورس ایران

 

اسامی کنترل های Textbox را به ترتیب از بالا به پایین txtFirstName، txtLastName، txtEmail، txtUserName، txtPassword و txtConfirmPassword نام گذاری کنید. همچنین اسامی کنترل های دکمه را به ترتیب به btnCreate، btnCreateAndNew و btnCancel تغییر نام دهید. همچنین به کنترل StatusStrip یک label با نام statusMessage و با خاصیت Text “آماده به کار” اضافه نمایید. همچنین یک کنترل ErrorProvider را به فرم اضافه نمایید. تا این مرحله ما تمامی قسمت UI Controls از لایه UIL را طراحی کردیم. اگر اکنون به قسمت Designer.Cs هر یک از فرم ها نگاه کنید می توانید متوجه شوید که چرا در این لایه تمامی تعاریف کنترل ها را از تعاریف متدها و رویداد ها در این لایه جدا در نظر می گیرند. تمامی این جدا سازی ها تنها به دلیل توسعه راحت پروژه در آینده و نیز کاهش پیچیدگی می باشد. بر روی دکمه “ایجاد” دابل کلیک کنید تا به محیط کد نویسی منتقل شوید و سپس کد زیر را به این رویداد اضافه کنید.

 CreateMember(); 

نگران خطاهای فعلی برنامه نباشید. مرحله به مرحله آنرا کامل می کنیم. سپس در رویداد کلیک دکمه “ایجا و جدید” کدهای زیر را وارد کنید. 

CreateMember();
EmptyBoxes();

در رویداد کلیک دکمه “انصراف” نیز کدهای زیر را وارد کنید 

this.Close();
this.Dispose();

سپس تعاریف متدهای استفاده شده در بالا را بصورت زیر وارد کنید 

private void CreateMember(){

       statusMessage.ForeColor = Color.Black;

       statusMessage.Text = @"آماده به کار";

       Control controlToSetError = null;

       errorProvider1.Clear(); // reset the control error

       try {

            UserEntity newUser = new UserEntity();

            controlToSetError = txtFirstName;

            newUser.FirstName = txtFirstName.Text;

            controlToSetError = txtLastName;

            newUser.LastName = txtLastName.Text;

            controlToSetError = txtEmail;

            newUser.Email = txtEmail.Text;

            controlToSetError = txtUserName;

            newUser.UserName = txtUserName.Text;

            controlToSetError = txtPassword;

            newUser.Password = txtPassword.Text;

            controlToSetError = txtConfirmPassword;

            newUser.ConfirmPassword = txtConfirmPassword.Text;

            UserController uc = new UserController();

            uc.Add(newUser);

            const string strMessage = @"عملیات با موفقیت انجام شد";

            statusMessage.Text = strMessage;

            MessageBox.Show(strMessage);

      }

      catch (Exception exp){

           if (exp is NotImplementedException && controlToSetError != null ){

               errorProvider1.SetError(controlToSetError, exp.Message);

               statusMessage.ForeColor = Color.Red;

               statusMessage.Text = exp.Message;

           }

           else{

                MessageBox.Show(exp.Message); // another exception raises

        }

      }

}

private void EmptyBoxes(){

       txtFirstName.Text = string.Empty;

       txtLastName.Text = string.Empty;

       txtEmail.Text = string.Empty;

       txtUserName.Text = string.Empty;

       txtPassword.Text = string.Empty;

       txtConfirmPassword.Text = string.Empty;

}

2.لایه منطق کاریBLL

این لایه قلب معماری 3-لایه می باشد. این لایه همان Controller ها در معماری MVC هستند. این لایه مسئول بررسی منطق اصلی برنامه و پردازش درخواست های کاربر و ارسال نتایج پردازش شده به شکل مناسب به کاربر می باشد. این لایه درخواست هایی را تنها از لایه UIL می گیرد و  در صورت نیاز دستوراتی را به لایه DAL صادر می کند و با پردازش آنها، نتایج را به لایه UIL می فرستد. این لایه نیز به دو قسمت تقسیم می شود.

الف )  BL Components/Controllers

این بخش شامل تعاریف اصلی کلاس هایی می باشد که باید محاسبات را انجام دهند. به عبارت دیگر تمامی رفتارهای محاسباتی، در این بخش قرار می گیرند. معمولا به ازای هر موجودیت اصلی در سیستم، یک کلاس با نام آن موجودیت و با پسوند Controller در این لایه تعریف می شود. برای مثال برای موجودیت User می توان عنوان UserController را بکار برد. هر Controller اگر نیازی به ارتباط با دیگر موجودیت ها داشته باشد، باید از طربق Controller آن موجودیت درخواست خود را صادر نماید. به عنوان یک استاندارد سعی کنید که برای نام گذاری متدها در این قسمت از اسامی سطح بالا و نه اسامی سطح پایگاه داده ای استفاده کنید، برای مثال برای گرفتن لیست کاربران واژه Get() بهتر از واژه Select() است. البته رعایت این اصول الزامی نمی باشد و تنها جنبه خوانایی و فهم کد را بالا می برد.

ب )   BL Entity

در این بخش تعاریفی قرار می گیرد که تنها شامل ویژگی ها و خصوصیات موجودیت ها می باشند. تعاریف موجود در این بخش بین تمامی لایه ها مشترک می باشد و از آنها برای پاس دادن اطلاعات بین بخش ها و لایه های مختلف استفاده می شود. همچنین برخی از بررسی های سینتکسی(Syntax) داده ها در این لایه انجام میگیرد. در برخی از منابع، به این لایه، لایه Common نیز گفته می شود.

برای اضافه کردن لایه منطق کاری به پروژه، بر روی پروژه راست کلیک کرده و در زیر منوی Add گزینه New Folder را انتخاب کنید و عنوان Common را وارد کنید. سپس بر روی این پوشه کلیک راست کنید و در منوی Add گزینه Class  را انتخاب کنید و در پنجره باز شده آیتم Class را انتخاب کنید و بعد از وارد کردن عنوان UserEntity برای این کلاس، کلید enter را فشار دهید. در این مرحله ما به طراحی کلاس Entity مربوط به موجودیت User در پروژه می پردازیم.کلاس های Entity تنها شامل خصوصیات و ویژگی های موجودیت ها می باشند و معمولا به ازای هر موجودیت اصلی در پروژه یک کلاس Entity نیز تعریف می شود. برای شروع کار، این کلاس را باز کرده و کلمه کلیدی public را در خط تعریف این کلاس قبل از کلمه class وارد کنید. این کار باعث می شود که این کلاس در سایر لایه ها قابل رؤیت باشد. و سپس کدهای زیر را به این کلاس اضافه کنید. 

private string _firstName;

private string _lastName;

private string _userName;

private string _password;

private string _confirmPassword;

private string _email;

private long _id;

public string FirstName{

      get { return _firstName; }

      set { // you can do syntax checked here

          if (string.IsNullOrEmpty(value))

            throw new NotImplementedException(@"لطفا فیلد نام را وارد کنید");

          _firstName = value.TrimStart(' ').TrimEnd(' ');

      }

}

public string LastName{

      get { return _lastName; }

      set { _lastName = value.TrimStart(' ').TrimEnd(' ');}

}

public string UserName{

      get { return _userName; }

      set {

          if (string.IsNullOrEmpty(value))

            throw new NotImplementedException(@"نام کاربری خود را وارد کنید");

          if (!UseValidChar(value))

            throw new NotImplementedException(@"استفاده از کاراکترهای غیر مجاز در نام کاربری");

          //remove the start and end space char. you must do this, to future search in db be easy

          // for examle, the "SourceIran" username has different with " SourceIran" or "SourceIran "

          _userName = value.TrimStart(' ').TrimEnd(' ');

      }

}

public string Password{

      get { return _password; }

      set {

          if (string.IsNullOrEmpty(value))

            throw new NotImplementedException(@"رمز عبور خود را وارد کنید");

          if (!UseValidChar(value))

            throw new NotImplementedException(@"استفاده از کاراکترهای غیر مجاز در رمز عبور");

          //CAUTION: never not used the Trim method, you must don't manipulate the user password

          _password = HashPassword(value);

      }

}

public string ConfirmPassword{

      get { return _confirmPassword; }

      set {

           if (string.IsNullOrEmpty(value))

             throw new NotImplementedException(@"رمز عبور یکسان نیست");

           _confirmPassword = HashPassword(value);

           if (_confirmPassword != _password)

             throw new NotImplementedException(@"رمز عبور یکسان نیست");

      }

}

public string Email{

      get { return _email; }

      set {

           if (string.IsNullOrEmpty(value))

             throw new NotImplementedException(@"آدرس ایمیل خود را وارد کنید");

           if (!IsValidEmail(value))

             throw new NotImplementedException(@"آدرس ایمیل نا معتبر می باشد.");

           _email = value.TrimStart(' ').TrimEnd(' ');

      }

}

public long Id{

      get { return _id; }

      set { _id = value; }

}

اگر به دقت به این کلاس نگاه کنید می توانید متوجه شوید که این کلاس تمامی خصوصیات موجودیت User را که در طراحی سیستم دخیل هستند را در خود دارد. سعی کنید که تا  جایی که امکان دارد بررسی های Syntax ایی مربوط به داده های هر خصوصیت را در این کلاس انجام دهید.

برای طراحی لایه منطق کاری یا همان BLL بر روی پروژه راست کلیک کنید و در منوی Add گزینه New Folder را انتخاب کنید و عنوان BLL را وارد کنید. سپس بر روی این پوشه کلیک راست کنید و در منوی Add گزینه Class را انتخاب کنید و یک کلاس جدید با عنوان UserController را به پروژه اضافه کنید. همانند کلاس UserEntity، modifier این کلاس را به public تغییر دهید. در این مرحله پروژه شما باید مشابه با شکل زیر باشد.

آموزش مفاهیم معماری 3-لایه، معماری n-layer
آموزش مفاهیم معماری چند لایه

 اکنون کدهای زیر را به این کلاس اضافه کنید.

public void Add(UserEntity newUser){

      UserManager.Insert(newUser);

}

public UserEntity Get(string userName, string password){

      UserEntity user = UserManager.Select(userName, password);

      return user;

}

public void UpdateInfo(UserEntity user){

      UserManager.Update(user);

}

public void Remove(string userName){

      UserManager.Delete(userName);

}

همانطور که مشاهده می کنید این کلاس شامل رفتارهای موجودیت User می باشد. این کلاس اطلاعات User را از کلاس UserEntity در لایه Common می گیرد و برای دسترسی به داده ها از لایه DAL استفاده می کند. این لایه  را در بخش بعدی شرح می دهیم. هوش اصلی و منطقی برنامه در لایه منطق کاری قرار دارد و تمامی پردازش های معنایی یا Semantic بر روی داده ها در این لایه انجام می گیرد.

دقت کنید که ما در این پروژه از مفهوم Layer استفاده کرده ایم و نه مفهوم Tier. چرا که تمامی کلاس ها و پوشه ها که معرف لایه ها می باشند تنها در یک پروژه تعریف شده اند و همگی این لایه ها در یک فایل اجرایی قرار دارند.

در قسمت های بعدی این مقاله با هم Tier لایه منطق کاری و همچنین لایه دسترسی به داده را بطور کامل شرح می دهیم.

دانلــود بـاکـــس

لینک های دانلود در این باکس قرار دارد
img

جهت مشاهده لینک های دانلود ابتدا وارد شده یا ثبت نام کنید

Avatar
پشتیبان سورس ایران 2180 مطلب منتشر شده

در مجموعه سورس ایران سعی می کنیم علاوه بر آموزش برنامه نویسی، به مسائل مرتبط و مهارت های نرم بپردازیم تا بعدهای مختلف را پوشش دهیم.

دیدگاه کاربران

تعداد دیدگاه های کاربران : ۱ دیدگاه
Avatar
محمد
پاسخ دهید

عالی


شما با موفقیت در خبرنامه ما عضو شدید