الگوهای طراحی در ‌javascript - بخش دوم

توی پست قبلی ما الگوهای طراحی رو تعریف کردیم و با کاربردشون آشنا شدیم و علاوه بر اون الگوی Null Object رو باهم بررسی کردیم و دیدیم که چطور با استفاده از این الگو میشه حالت‌هایی که شیء مدنظر ما null یا undefined هست رو هندل کنیم.

حالا داخل این پست میخوایم ۲ مورد دیگه از الگوهای طراحی و کاربردشون رو باهم بررسی کنیم :

۱ – الگوی Builder که جزء الگوهای طراحی سازنده (Creational Design Patterns) هست

۲ – الگوی Facade که جزء الگوهای طراحی رفتاری (Structural Design Patterns) هست

الگوی Builder :
خیلی از مواقع ما نیاز داریم یک شیء خیلی بزرگ بسازیم که attributeهای زیادی میتونه داشته باشه. مثلا یک شیء user رو درنظر بگیرید که میتونه attributeهایی مثل نام ، سن ، تلفن ، ایمیل ، آدرس ، auth token و ... داشته باشه. اگر بخوایم این شیء و attribute های اون رو با استفاده از constructor کلاس user بسازیم ، کدمون اینطوری میشه.

حالا ما موقع ساختن این شیء مجبوریم تمام attribute هارو پاس بدیم. این attribute ها معمولا غیر از نام و گاهی اوقات شماره تلفن ، ‌optional هستن. حالا اگه نخوایم این ‌attribute های optional رو ست کنیم ، باید اینطوری شیء یوزر رو بسازیم.

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

راه حل این مشکل الگوی Builder هستش. دو مدل پیاده‌سازی الگوی Builder رو باهم بررسی میکنیم. مدل اول شکل اصلی و اورجینال این الگو هستش و مدل دوم راه حلی هست که یه مقدار جاوااسکریپتی تره

مدل اول :

- در مرحله اول ما یک کلاس UserBuillder می‌سازیم و داخل constructor فقط مقادیر اصلی و required رو ست میکنیم.

- در مرحله بعد برای هرکدوم از attribute های ‌optional یک متد داخل کلاس UserBuilder اضافه میکنیم.

- و در آخر یک متد builder اضافه میکنیم که شیء ‌user رو برای ما return میکنه.

ازین به بعد برای ساختن شیء user از کلاس UserBuilder استفاده میکنیم و فقط کافیه نام رو ست کنیم. برای بقیه attribute ها هر کدوم رو که خواستیم ست کنیم ، متدش رو روی شیء مدنظرمون صدا می‌زنیم. دقت کنید که داخل متدها this رو return کردیم تا بتونیم متدهارو chain کنیم.

مدل دوم (جاوااسکریپتی) :

راه حل ساده تر جاوااسکریپت برای ست کردن attribute های optional اینه که اونا به صورت ‌object پاس بدیم. و فقط همین :)

در این صورت میتونیم از کلاس UserBuilder صرف نظر کنیم و اینکارو داخل خود کلاس ‌‌َUser انجام بدیم.

همونطور که دیده میشه، میتونیم attribute های optional رو به صورت { key: value } پاس بدیم. و چون داخل constructor ، برای attribute های optional ، یک آبجکت خالی رو به عنوان پیش فرض ست کردیم ، اگر موقع ساخت شیء مقداری رو براشون درنظر نگیریم ، برابر با undefined ست میشن. داخل مثال ما اگر user رو چاپ کنیم ، میبینیم که برای phone و email مقدار undefined ست شده.

من خودم به شخصه مدل اول رو بیشتر میپسندم. تر و تمیز تره :) و خب مدل دوم شاید یکم از کانسپت اصلی الگو دور بشه ... شماهم نظرتون رو برام کامنت کنید

بریم برای الگوی بعدی

الگوی Façade :

یطور کلی این الگو برای این هستش که تغییرات کد شما رو در آینده راحت کنه. الگوی Facade بیان میگه که ما باید پیچیدگی منطق برنامه رو انتقال بدیم به زیرسیستم‌ها. چجور اینکار انجام میشه ؟ با استفاده از یک interface. این interface رابط بین ما و زیرسیستم‌هایی هست که منطق اصلی برنامه داخلشون پیاده سازی شده. کارش هم اینه که اون چیزی رو که زیرسیستم‌ها میخوایم دریافت بکنیم رو بهمون ارائه میده. شاید پیچیده به نظر برسه ولی خیلی ساده تر ازین حرفاست و در عین سادگی به شدت پرکاربرده و کد رو تمیزتر و maintainable تر میکنه.

بریم یه مثال ازش ببینیم :

دوتا ریکوئست داریم که داخل یکی لیست یوزرها و داخل یکی دیگه پست‌‌های یک یوزر رو دریافت میکنیم. و در آخر هم چاپشون میکنیم.

الگوی Facade میگه که پیچیدگی منطق کد رو منتقل کنیم به زیرسیستم‌ها. بنابراین یک interface به اسم getFetch میسازیم و مابقی کدمون رو از متدهای‌ getUsers و getPosts خارج میکنیم. متد getFetch به شکل زیر درمیاد که با استفاده از url و param ی که بهش پاس میدیم ، ریکوئست مدنظر مارو return میکنه.

الان دیگه داخل متدهای getUsers و getPosts فقط از این interfaceاستفاده میکنیم. درواقع الگوی Facade باعث شد که متد getUsers ، کاری به منطق پیاده سازی ریکوئست‌ها نداشته باشه. فقط ریکوئستی رو که لازم داره با استفاده از getFetchدراختیارش قرار میدیم.

هم کد تمیزتری داریم ، هم تصور کنید بعدا خواستید به جای fetch از axios استفاده کنید. دراین صورت کافیه کدتون رو فقط یکجا تغییر بدین که اون هم داخل متد getFetch هستش. خیلی هم عالی :)


داستان الگوهای طراحی اینجا تموم نمیشه و هنوز ادامه داره ... خوشحال میشم نظراتتونو و پیشنهاداتتونو برام کامنت کنید :)