تو چند ماه اخیر که مشغول مصاحبههای کاری بودم، با سوالاتی روبهرو شدم که جوابشون به نظر ساده میاومد، ولی توی عمل خیلی پیچیده بودن. بعد از هر مصاحبه، وقتی جوابها رو بررسی میکردم، متوجه شدم که دیزاین پترنها کلید حل خیلی از این چالشها هستن.
اما چرا تو خیلی از پروژههای واقعی، کمتر کسی از این پترنها درست استفاده میکنه؟
توی شرکتهایی که کار کردم، دیدم که خیلی از توسعهدهندهها یا با دیزاین پترنها آشنا نیستن یا نمیدونن چطور باید ازشون توی پروژههای انگولار استفاده کنن.
برای همین تصمیم گرفتم توی این مقاله، یکی از مهمترین دیزاین پترنهایی که توی پروژههای انگولار حسابی به کارتون میآن رو با مثالهای ساده و کاربردی توضیح بدم. و تو مقاله های بعدی به پترن های مهم دیگه اشاره میکنم.
برخلاف مقالات تئوریک، اینجا تمرکزم روی مثالهاییه که میتونین مستقیم توی پروژههاتون استفاده کنین. هدفم اینه که بعد از خوندن این مقاله، بتونین با اطمینان بگین: «این پترن دقیقاً برای مشکل پروژهم عالیه!» . پس بیاید با هم این پترنها رو کشف کنیم و پروژههای انگولارتون رو ارتقا بدین.
من تو این مقاله Facade رو توضیح میدم و چندتا مثال میزنم تا خوب یادش بگیرید. در مقالههای بعدی با همین رویکرد پترنهای دیگه رو بررسی میکنیم.
دیزاین پترنها چی هستن و برا چی اومدن به بازار؟
اونا مثل یه جعبهابزار قویان برای ما دولوپرها، که کمک میکنن کدهای تمیزتر، مقیاسپذیرتر و قابلنگهداری بنویسیم.
خب، بسه لفظقلم صحبت کردن. اما دقیقاً چه مشکلاتی رو حل میکنن؟ وقتی پروژههای انگولار بزرگتر میشن، با چالشهایی مثل مدیریت پیچیدگی کد، هماهنگی بین سرویسها و کامپوننتها، یا حتی تغییر رفتار اپلیکیشن بدون بازنویسی کل کد مواجه میشیم.
دیزاین پترنها راهحلهای آزمایششدهای هستن که این مشکلات رو سادهتر میکنن. خب، چطوری؟
الان میخوام دربارهی یکی از این دیزاین پترنهای مهم و کاربردی بگم که ببینید چطور پروژهتونو بهینه میکنه.
من میخوام از یه سناریو شروع کنم. اول بگم که مثالا رو روی یه پروژه فروشگاهی میزنم.
بهطور مثال، میخوایم لیست محصولاتمون رو نشون بده، به سبد خرید اضافه کنه و در نهایت پرداخت کنه.
ما در مرحلهی اول میگیم باید سهتا سرویس بسازیم:
product.service، cart.service و payment.service. خب، ما میایم این سرویس ها رو به کامپوننتمون اینجک میکنیم. اگه یه نگاه کلی بخوای میشه این دیگرام:


کد بالا رو با دقت ببینید. خیلی ساده و سریعه، ولییی! به نظرت کامپوننت رو خیلی درگیر مدیریت منطق سرویسها نکردیم؟ یا اینکه خواناییش خوبه؟! خیلی اینجکت نکردیم؟ تستش چی؟ سهتا سرویس تزریق شده! حالا اگه ما سرویس تخفیف و لاگین رو بهش اضافه کنیم، چه اتفاقی براش میافته؟
درسته، اینجاست که با بزرگ شدن پروژه، هندل کردن این مسئله سختتر میشه.
خب، باید چیکار کنیم؟
تو این مسئله Facade Pattern به دادمون میرسه. چطوری؟
یکی از کارهایی که این پترن انجام میده، اینه که پیچیدگی یه ماژول رو برای کامپوننت یا کلاس پنهان میکنه و باعث میشه منطق UI و بیزینس قاطی نشن و اینجاست که کمکمون میکنه!
Facade میاد یه لایه بین کامپوننتها و سرویسها ایجاد میکنه تا پیچیدگی رو کم کنه و کد هم تمیزتر بشه. حالا بیا مثال بالا رو با این پترن جذاب بنویسیم. قبلش خودت حدس بزن، بعد ادامشو بخون. اگه هم نمیدونستی، اصلاً اشکالی نداره؛ اومدی که یادش بگیری.
اول یه دیاگرام کلی نشونت میدم که دیدت بازتر بشه:


اینجا ما یه رابط facade ساختیم که سه تا سرویس رو اینجا تزریق کنیم

و فقط سرویس Facade رو در کامپوننت تزریق کردیم و اینطوری کامپوننت درگیر مدیریت سرویس ها نمیشه.
دیدی چه خوشگل شد!
اینجا کامپوننت فقط با یه سرویس کار میکنه و از پیچیدگیهای زیرینش بیخبره؛ اگه هم بخواین سرویس جدیدی اضافه کنی مثل تخفیف، فقط Facade رو تغییر میدی. این میشه توسعه و نگهداری راحتتر.
یه نکته؛
در پروژههای بزرگ Facade رو به چند سرویس کوچکتر تقسیم کن و منطق هر فیچر جدا باشه و نذار Facade خیلی بزرگتر بشه چون خودش باعث پیچیدگی میشه و …
مثلاً همین لیست محصولات اگه ساده نگاش کنیم، یه لیست سادهست که چندتا رکورد رو نشون میده.
حالا من میگم یه لیست که loading و error داره؛ یه ترتیب نمایشه، یه فیلتر و یه pagination. حالا بیا و درستش کن!
اینجا دیگه نمیخوام حالت سادهشو بنویسم، خودت تو ذهنت حدس بزن که چطوری ساده میشه نوشت. بعدش با Facade طراحیش کن، منم این زیر پیادهش میکنم.

یه فایل سرویس Facade برای productList ساختیم و اینجکت ها رو انجام دادیم و subject ها رو داخلش ساختیم.

حالا میتونیم از سرویسهامون، هرکدومو میخوایم استفاده کنیم و اگه خواستیم سرویسه sort رو هم میشه بهش اضافه کرد.

و در نهایت Facade رو به کامپوننت اینجکت میکنیم:

جمع بندی:
Facade یکی از پرکاربردترین پترن ها در پروژه ها با اسکیل بزرگه، تو این مقاله دیدیم که چطوری میتونه بهمون در ساده سازی بخش هایی از پروژه کمکون کنه. همونطور که تو دیاگرام دیدید، Facade مثل یه فیلتر جادویی بین کامپوننت و سرویسها عمل میکنه و همهچیز رو سادهتر میکنه. علاوه بر سادگی، Facade تستپذیری رو بهتر میکنه و تو پروژههای بزرگ با ماژولهای Lazy-Loaded حسابی به کارتون میآد.
اگه از Facade تو پروژههات استفاده کردی، تو کامنت برام بنویس و تجربهتو رو به اشتراک بذار، مرسی!