الگوی طراحی Facade، یکی از الگویهای کابردی در توسعه و طراحی نرمافزار است. Facade به معنی نمای خارجی یا بیرونی است. به عنوان مثال نمای خارجی یک ساختمان را در نظر بگیرید که جزئیات و پیچیدگیهای داخلی را مخفی میکند. الگوی نما نیز به همین منظور استفاده میشود و پیچیدگیهای یک سیستم با تعداد زیادی کلاس را از دید کاربر پنهان میکند. در این مقاله این الگو را بررسی میکنیم.
دیزاین پترن Facade چیست؟
اگر زیرسیستمی (Subsystem) حاوی چند کلاس باشد و این کلاسها برای تدارک سرویسهای زیرسیستم با همدیگر همکاری کنند، ریسک ایجاد واسط به آن زیرسیستم وجود دارد. هر کلاس، ممکن است چندین عملیات داشته باشد؛ زیرسیستمهای دیگر باید توانایی ارسال پیام به نمونههایی از هر کلاس را داشته باشند.
به این ترتیب، یک اتصال قوی بین زیرسیستمها به وجود میآید و اگر تغییر در کلاسهای یک زیرسیستم ارائه دهنده سرویس به وجود بیاید، نیازمند ردیابی تمامی مکانها در زیرسیستمهایی هستیم که عملیات این کلاس ها را فراخوانی کردهاند. برای غلبه بر این وضعیت میتوان از الگوی Facade استفاده کرد.
نحوه عملکرد الگوی Facade
با ایجاد کلاس Facade، واسطی را به زیرسیستم اضافه میکنیم. این کلاس به عنوان نماینده زیرسیستم مورد نظر با زیرسیستمهای دیگر عمل میکند. به این ترتیب، تغییر در پیادهسازی کلاسهای زیرسیستم اثر محدودی بر زیرسیستمهای دیگر دارد. همچنین اگر تغییری در کلاسها صورت بگیرد، فقط لازم است نقاطی در زیرسیستمهای دیگر پیدا شود که در آنها، پیامی به نمونههای کلاس Facade ارسال شده است.
بنابراین این الگو با به کارگیری مکانیسمی، دسترسی آسان کاربر به زیرسیستمها را فراهم میکند. گفتنی است، SubSystem به مجموعهای از کلاسها گفته میشود که با هم در ارتباط هستند و برای تامین یک هدف و منظور خاص با هم کار میکنند.
کاربر مربوط به این SubSystemها شاید نیاز داشته باشد با تعدادی از این کلاسها کار کند که ارتباط مستقیم کاربر با کلاسها، همبستگی بین آنها را بالا میبرد. زمانیکه درون زیرسیستم تغییراتی داشته باشیم، کاربر آن نیز مجبور به تغییرات میشود.
مساله دیگر این است که کاربر باید منطق کل سیستم را بداند که پیچیدگی خاص خود را دارد. برای رفع این مشکل از الگوی Facade استفاده میکنیم؛ به این شکل که یک واسط ساده همانند یک پوسته روی کل زیرسیستم قرار میدهیم و هر زمان کاربر بخواهد از کلاسهای زیرسیستم استفاده کند، از این واسط استفاده میکند. با این عمل وابستگی کمتر و مدیریت آن آسانتر میشود.
مثالی از استفاده Facade Design Pattern
به عنوان مثال تصور کنید شما به عنوان مدیر پروژه برای یک پروژه نسبتا بزرگ انتخاب شدهاید. در حالت اول شما خودتان وظیفه دارید مسئولیت تک تک افراد پروژه را به آنها بگویید و وظایف واگذار شده به آنها را تحویل بگیرید. در این حالت شما وظیفه دارید با تک تک افراد ارتباط برقرار کنید و همچنین برای بازخواست وظایف، شما باید نحوه ارتباط این افراد را با یکدیگر بدانید.
در حالت دوم یک نفر به عنوان سرگروه انتخاب میشود و شما مسئولیتهای واگذار شده را به او اعلام میکنید و برای تحویل وظایف فقط با او ارتباط برقرار میکنید. با مقایسه دو حالت متوجه میشویم که در حالت دوم پیچیدگی و حجم کاری شما کمتر است. در واقع در حالت دوم از الگوی Facade استفاده کردهاید. سرگروه در این حالت به عنوان کلاس Facade است.
ویژگیها و اجزای الگوی Facade
Class Diagram
در شکل زیر کلاس دیاگرام مربوط به این الگو را میبینید.
بنابر گفته GoF هدف از الگوی Facade عبارت است از:
تهیه یک واسط يكپارچه برای مجموعهای از واسطها در یک زیرسیستم. Facade، با تعریف یک واسط سطح بالاتر، استفاده از زیرسیستم را سـادهتـر مـیكنـد.
شکل ۱: کلاس دیاگرام الگوی Facade
نقش کلاسها
- Facade:
کلاسی که تمام زیرسیستمها را میشناسد و میداند جواب درخواست کلاینت را باید از کجا بگیرد.
- Subsystem classes:
پیادهسازی وظایفی که یک زیرسیستم دارد، راهاندازی درخواستهایی که از طرف Facade صادر میشود در حالی که هیچ دانشی در خصوص Facade و هیچ ارجاعی به آن ندارد.
سایر ویژگیهای کلیدی الگوی طراحی Facade
در جدول زیر به صورت خلاصه هدف الگو، نام یا نامهای دیگری که الگو با آن شناخته میشود، مواقعی که میتوانیم از این الگو استفاده کنیم، مزایا و معایب استفاده از این الگو و الگوهای مرتبط به این الگو را توضیح دادهایم.
جدول ۱: ویژگیهای Facade
عنوان |
شرح |
نام |
Facade Pattern |
هدف |
به جای مجموعه واسطهای موجود در سیستم، یک واسط واحد از یک زیرسیستم ارائه بدهد. |
نامهای دیگر |
ندارد |
کاربرد |
زمانی از این الگو استفاده کنید که:
|
نتایج |
مزایای این الگو:
معایب این الگو:
|
الگوهای مرتبط |
|
یک مثال برای الگوی طراحی Facade
در زیر مثالی از این الگو پیادهسازی شده است:
مساله: قصد داریم یک برنامه کاربردی برای پرداخت وام به مشتری پیادهسازی کنیم که از یک زیرسیستم استفاده میکند تا ببیند مشتری شرایط احراز وام را دارد یا خیر.
راهحل: برای پیادهسازی از الگوی Facade استفاده میکنیم.
در اینجا کلاسهای Bank ،Credit ،Loan ،Mortgage و Customer را داریم.
Bank: موجودی بانک را برای پرداخت وام بررسی میکند.
Credit: اعتبارات بانک را بررسی میکند.
Loan: بازپرداختی وامهای قبلی را چک میکند.
مجموعه این سه کلاس زیرسیستم ما را تشکیل میدهند.
Customer: مشخصات مشتری مورد نظر را دارد.
Mortgage: در این کلاس شرایط احراز بررسی میشود؛ به این صورت که این کلاس طبق کلاس دیاگرام، نقش کلاس Facade را دارد و در آن یک متد به نام IsEligible وجود دارد که شرایط احراز را بررسی میکند.
مزیت استفاده از این الگو: با استفاده از این الگو، کاربر فقط مشخصات خود را به بانک میدهد و بانک بررسی میکند که شرایط وام گرفتن دارد یا خیر. بنابراین کاربر نیازی به دانستن پیچیدگیهای هر کدام از کلاسهایی که برای بررسی شرایط پرداخت وام ایجاد شده را ندارد.
پیادهسازی:
namespace Mortgage_Facade {
class Program {
static void Main(string[] args) {
Mortgage mortgage = new Mortgage();
Customer customer = new Customer("Behnoosh");
bool eligible = mortgage.IsEligible(customer, 50000);
Console.WriteLine("\n" + customer.Name +" has been " + (eligible ? "Approved" :
"Rejected"));
Console.ReadKey(); } } }
class Bank {
public bool HasSufficientSavings(Customer c, int amount) {
Console.WriteLine("Check bank for " + c.Name);
return true; } }
class Credit {
public bool HasGoodCredit(Customer c) {
Console.WriteLine("Check credit for " + c.Name);
return true; } }
class Loan {
public bool HasNoBadLoans(Customer c) {
Console.WriteLine("Check loans for " + c.Name);
return true; } }
class Customer {
private string _name;
public Customer(string name) {
this._name = name; }
public string Name {
get { return _name; } } }
class Mortgage {
private Bank _bank = new Bank();
private Loan _loan = new Loan();
private Credit _credit = new Credit();
public bool IsEligible(Customer cust, int amount) {
Console.WriteLine("{0} applies for {1} loan\n",cust.Name, amount);
bool eligible = true;
if (!_bank.HasSufficientSavings(cust, amount)) {
eligible = false; }
else if (!_loan.HasNoBadLoans(cust)) {
eligible = false; }
else if (!_credit.HasGoodCredit(cust)) {
eligible = false; }
return eligible; } }
خروجی:
جمعبندی
در این مقاله سعی کردیم با بیان چند مثال، الگوی طراحی Facade را که یک الگوی کاربردی برای سیستمهای پیچیده است بررسی کنیم. استفاده از این الگو مانند ایجاد واسطی برای مدیریت راحتتر فرایندها و زیرسیستمها است و به شما در کاهش پیچیدگی سیستم و انجام فرایندها کمک میکند.
دیدگاهتان را بنویسید