حوزه: Object
هدف: Structural
نقش الگو
یک الگوی رایج که توسط کلاینتهای SOA استفاده میگردد، الگوی Facade است. الگوی Facade برای ساده سازی واسط یک زیر سیستم یا گروهی از زیرسیستمها به کار میرود و به کلاینت، یک API ساده و شفاف میدهد تا با سایر APIها سازگار باشد.
الگوی Facade یک واسط ساده برای API پیچیده فراهم میکند. این الگو میتواند در سناریوهای مختلفی به کار رود:
- آن میتواند یک کتابخانه ترد پارتی سادهتر سازد با پوشش دادن در یک واسطی که با بقیه سیستم سازگار باشد.
- آن کمک میکند که کد مستقل از یکدیگر داشته باشیم با انتزاع کردن وابستگیها به سیستمهای و کتابخانههای دیگر.
- میتواند برای یک زیر سیستم پیچده، واسط سادهای را ارائه کند. این در نمودار UML زیر آمده است.
الگوی Facade میتواند در لایه سرویس استفاده شود برای اینکه پیچیدگیهای ارتباط با برنامه کاربردی راه دور را با استفاده از وب سرویس پنهان کند.
UML
مشکل
فرض کنید که شما چندین عملیاتی را دارید که میخواهید به ترتیب انجام شوند، و اینکه یک عمل(Action) یکسان هم در مکانهای مختلف برنامه شما مورد نیاز است و بالطبع کدهای این عمل یکسان در مکانهای مختلف برنامه شما قرار خواهند داشت. اما پس از چند روز شما نیاز به انجام تغییراتی در همان کدها را خواهید داشت.
آیا متوجه مشکل شدید؟ ما باید این تغییرات یکسان و مشابه را در مکانهای مختلفی که آن کدها در آنجا قرار دارند را انجام دهیم. آیا این زجر آور نیست؟
راه حل
بعنوان یک راه حل، چیزی که ما باید انجام دهیم این است که یک کنترلگر بسازیم که وظیفه مدیریت تمام کدهایی که تکراری هستند را به عهده بگیرید. آنگاه ما تنها نیاز به فراخوانی این کنترلگر خواهیم داشت تا عمل (Action) بر اساس پارامترهای ارائه شده انجام شود.
حال اگر ما نیاز به انجام هرگونه تغییری در روند عملیات را داشته باشیم، تنها این تغییرات را در کنترل گر انجام می دهیم بجای اینکه در نقاط مختلف کدها این تغییرات مشابه را اعمال کنیم.
تشریح یک مثال
اجازه دهید برای روشن شدن موضوع یک مثالی را ذکر کنیم. فرض کنید که وظیفه برنامه ریزی مراسم ازدواج یکی از دوستانتان به شما داده شده است. حجم کارهایی که باید انجام شود را تصور کنید. حال اگر تمامی کارها را خود به تنهایی بخواهید انجام دهید. خب بالطبع باعث میشود که درصد خطا بیشتر شود و همچنین ممکن است کارهایی را از قلم بیاندازید و در نتیجه مراسم ازدواج دوستتان به هم بریزد.
در این مورد، بجای اینکه تمام کارها را خود به تنهایی انجام دهید، شما باید از یک برنامه ریز مراسم ازدواج استفاده کنید که مطمئن شوید کلیه کارها به خوبی و به موقع و با شانس خطای کمتری انجام شوند.
در اینجا، شما نقش یک مشتری (Client) که کار شروع این پروسه را به عهده دارد و برنامه ریز مراسم ازدواج بعنوان یک (Facade) برای شما کار خواهد کرد، یعنی کامل کردن کارها بر اساس جهت و خواستهای که شما تعیین میکنید.
مثالی با کدنویسی
در این بخش یک مثال با موضوع پروسه خرید یک محصول که در وب سایتها خیلی معمول و مرسوم است را همراه با مقداری کدنویسی مرور میکنیم. اما قبل از اینکه ما بخواهیم به طور کامل کدهای پیاده سازی شده با الگوی طراحی نما را بررسی کنیم اجازه دهید کدی را مرور کنیم که دارای یک مشکل است.
یک پروسه ساده خرید یک کالا دارای گام های زیر است:
- افزودن کالا به سبد.
- محاسبه هزینه حمل و نقل.
- محاسبه تخفیف.
- ایجاد سفارش.
Cart cart = new Cart();
Scanner scanner = new Scanner(System.in);
Integer productId = scanner.nextInt();
ProductQty productQty = new ProductQty();
if (productQty.checkQty(productId)) {
// افزودن کالا به سبد
cart.addToCart(productId);
// محاسبه هزینه حمل و نقل
ShippingCharge shippingCharge = new ShippingCharge();
shippingCharge.updateCharge();
// محاسبه تخفیف
Discount discount = new Discount();
discount.applyDiscount();
// ایجاد سفارش
Order order = new Order();
order.generateOrder();
}
در کدهای بالا شما شاهد این هستید که روند خرید شامل اشیاء مختلفی است که نیاز به ایجاد شدن دارند تا عمل خرید کامل شود، خب حالا تصور کنید این روند را بخواهید در چندین مکان پیاده سازی کنید و بعد از مدتی بخواهید تغییراتی را در کدهایتان انجام دهید، خب مسلما مشکل ساز خواهد بود.
حال میخواهیم همین روند خرید را به روش الگوی طراحی نما (Facade) پیاده سازی کنیم، که در اثر آن کدهای ما قابل نگاهداری و توسعه پذیرتر خواهند بود.
public class ProductOrderFacade {حال الگوی طراحی نما (Facade) روند خرید ما آماده است. تمام آن چیزی را که باید انجام دهیم استفاده از آن با برخی کانالهای ارتباطی کد است، بجای استفاده از دستهای از کدها همانطوری که در بخش قبل بیان شد.
public void generateOrder() {
// محاسبه هزینه حمل و نقل
calulateShipping();
// محاسبه تخفیف
applyDiscount();
//ایجاد سفارش
placeOrder();
}
public void addToCart(Integer productId) {
if (qtyCheck(productId)) {
/* .. افزودن کالا به سبد .. */
}
}
private boolean qtyCheck(Integer productId) {
// 'get product quantity from database where id=productId'
Integer qty = 1;
if (qty > 0) {
return true;
} else {
return true;
}
}
private void calulateShipping() {
ShippingCharge shippingCharge = new ShippingCharge();
shippingCharge.updateCharge();
}
private void applyDiscount() {
Discount discount = new Discount();
discount.applyDiscount();
}
private void placeOrder() {
Order order = new Order();
order.generateOrder();
}
}
حال کدهایی که برای روند خرید لازم است تنها چند خط زیر خواهد شد.
ProductOrderFacade productOrderFacade = new ProductOrderFacade();حال تصور کنید زمانی که بخواهید تغییراتی را در روند خرید انجام دهید تنها کافیست این تغییرات را در کلاس نمای آن که ساخته بودیم انجام دهید بجای آنکه در مکانهای مختلف کدهایتان این تغییرات مشابه را انجام دهید.
productOrderFacade.addToCart(1);
productOrderFacade.addToCart(4);
productOrderFacade.generateOrder();
نتیجه گیری
مثال پیاده سازی شده با زبان جاوا را میتوانید از github من دانلود کنید.
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.