نگه‌داری متغیرها توی پروژه‌های بزرگ در جاواسکریپت

اگر با جاواسکریپت و فریم‌ورک‌هایی مثل ری‌اکت، انگولار، ویو یا دوستای اون‌ها برنامه می‌نویسید و بطور کلی مفهوم کامپوننت رو می‌دونید، این متن برای شماست. من قرار نیست توی این پست Redux و Vuex یا هر لایبرری دیگه رو یاد بدم، بلکه می‌خوام توضیح بدم این‌هایی که گفتم چه کار می‌کنن و طرز کار کلیشون چجوریه.

حتما می‌دونید که معمولا توی پترن برنامه‌نویسی کلاینت، ما سه تا بخش اصلی داریم. بخش اطلاعات یا همون state که اطلاعات ما رو نگه میداره. بخش actions که فانکشن‌های ما که قراره اطلاعات رو تغییر بده توش نگه‌داری میشه و بخش نمایش یا view که صفحاتی که کاربر قراره اونا رو ببینه و دکمه‌هاشون رو فشار بده، توی این بخش قرار می‌گیره. در ادامه، ارتباط این سه تا رو نشون می‌دم.

Flow
Flow


اگه اپلیکیشن ما در حد نمایش یه سری اطلاعات ساده و کم و زیاد کردن اعداد باشه، میتونیم با همین روند کارمون رو ادامه بدیم. چون این الگو ساده و قابل‌فهم برای شروعه و هیچ مشکل خاصی نداره. حتی ما می‌تونیم محاسبات پیچیده رو با همین الگو پیاده کنیم. اما وقتی اپلیکیشن ما بخواد بزرگ بشه، ممکنه ما اذیت بشیم. چرا؟ چون با گوشت‌کوب هم میشه میخ رو به دیوار کوبید، ولی اگه شما نجار باشی، برای ساختن یه صندلی بزرگ ممکنه بدون چکش دستتون رو زخم کنید. توی ادامه متن براتون توضیح میدم که چرا ممکنه دستمون زخم بشه.

فرض میکنیم برنامه ما یه برنامه‌ایه که کاربرها میتونن توش login کنن و یه سری دکمه رو بزنن و وقتی کارشون تموم شد، logout کنن. وقتی چندتا کامپوننت یا تمپلیت بخوان یه متغیر خاص مثلا وضعیت login کاربر رو نشون بدن و اتفاقا بعضی‌های دیگه‌شون بخوان اون رو تغییرش بدن، یکم اوضاع گوریده میشه به هم. درسته این کار شدنیه، ولی ما باید هی این متغیر رو به اون کامپوننت‌ها پاس بدیم. وقتی برنامه بزرگ باشه، ممکنه صاحب این متغیر خاص که گفتم، خود این کامپوننت لود شده نباشه و کامپوننت پدر که الان سه نسل با اون فاصله داریم صاحبش باشه. به عبارتی ما نمیتونیم به این نوه جدید بگیم متغیر وضعیت login رو تغییر بده، باید بگیم من دات پدرم دات پدرش دات متغیر وضعیت login رو تغییر بده. بعد تازه چون این متغیر خاص بین همه اونها مشترکه، وقتی یکیشون تغییر ایجاد میکنه بقیشون هم باید خبردار بشن و مشتقات این تغییر رو روی خودشون اعمال کنن. حالا تصور کنید خدا عمر با عزت به این فامیل عطا کنه و دارای هفت هشت تا نسل بشه. اون وقت آدرس‌دادن و مدیریت کردن تغییرات این متغیر بین کامپوننت‌ها پیچیده، سنگین و گیج کننده میشه. دیگه نگم که دخترعمو/پسرعموها هم بخوان با هم ازدواج کنن! این جوری اپلیکیشن ما میشه یه سالن کوچیک که هزارتا آدم دارن توش همدیگه رو صدا میکنن و هی با همدیگه کار دارن و کلی بچه هم اون وسط دارن کله‌ملق بازی می‌کنن.

راه حل چیه؟

ما میتونیم تصاحب این متغیرها رو از روی دوش کامپوننت‌ها برداریم و اونها رو توی یه آبجکت عمومی global نگه‌داری کنیم. اینطوری همشون اون رو میشناسنش و دیگه مشکل گوریدن نداریم. اما صبر کنید. اگه مثلا یه متغیر بخواد فقط تحت تصاحب خونواده خاله و نوه نتیجه اونها باشه و بقیه حق دخالت نداشته باشن چی؟ برای حل این یکی ما می‌تونیم از namespace یا آبجکت‌های من درآوردی دیگه یا ماژولار کردن اونها استفاده کنیم و حق تغییر و استفاده از اون‌ها رو به کامپوننت‌هامون بسپریم. جوری که متغیرها توی هم قاطی نشن. اما دوباره یه مشکل پیش میاد. بحث اختراع دوباره چرخ. اگه شما از دسته مخترعین عزیز هستین و دوست دارین این مشکل رو با روش‌های خودتون حل کنید، حق تصمیم‌گیری با شماست. ولی زمانی که بیشتر از یک نفر بخوان توی توسعه این برنامه شرکت کنن، این کار خیلی خودخواهانه‌ست. ما باید سعی کنیم از یه روش استاندارد عمومی که همه بهش دسترسی دارن و می‌تونن از کلی مطلب موجود اون رو یاد بگیرن استفاده کنیم تا اینکه چرخ‌های رنگارنگ جدید تولید کنیم.

استیت منجرها یا State Managerها برای همین ساخته شدن. برای اینکه تصاحب این متغیرها از روی دوش کامپوننت‌ها برداشته بشن. اونها در عوض میان وسط و توی هر کامپوننت یه آبجکت میدن که ما میتونیم متغیرها رو توی اون بنویسیم. هرکس دیگه‌ای هم از فامیل خواست به اون‌ها دسترسی داشته باشه، می‌تونیم حق دسترسی بهشون بدیم و متوجه بشیم کی سعی می‌کنن تغییرش بدن. درواقع این عضو خانواده رو می‌تونید شخص مادر توی هر فامیل این خونواده بزرگ درنظر بگیرید. مادرها از تغییرات فرزنداشون خبردار می‌شن و با یه زنگ به خاله و عمه‌ها می‌تونن حال‌واحوال اونها رو جویا بشن و اتفاقات خونوادگی رو باهاشون در میون بذارن. توی حالت جدید، ارتباط بخش‌های برنامه در یک فریمورک خاص مثل Vue بصورت زیر می‌شه.

Vuex
Vuex


کی به State Managerها نیاز پیدا می‌کنم؟

این سوالیه که جوابش دست شماست. اگرچه خود فریم‌ورک‌های ویو و ری‌اکت و… می‌تونن متغیرهای ما رو نگه‌داری کنن و امکانات و متودهایی برای تغییر اون‌ها و باخبرشدن از تغییراتشون در اختیار ما قرار میذارن، اما موضوع اندازه برنامه ماست. اگر برنامه‌تون داره بزرگ می‌شه و دارید توی نگه‌داری متغیرها به مشکل می‌خورید و اوضاع پیچیده شده، قدم بعدیتون می‌تونه State Manager باشه. درنهایت، توضیحات این مطلب رو با یک جمله آب‌طلاپسند از Dan Abramov، سازنده لایبرری Redux به پایان می‌برم:

کتابخونه های فلاکس مثل عینک می‌مونن، وقتی بهشون نیاز داشته باشی، خودت میفهمی.