اگه قبلا اسم Proxy آبجکت ها باعث میشد که یهو بگید "ای بااباا این دیگه چیه... ولمون کن" باید بگم تنها نبودید ? منم تا قبل اینکه از قابلیت های فراوون Proxy ها خبر داشته باشم همچین فکری میکردم. ولی بعد که باهاش بیشتر آشنا شدم و فهمیدم چه کارای باحالی میشه باهاش کرد تصمیم گرفتم روش بیشتر فکر کنم و نظرم عوض شد!
واقعا خفن و خوشگله. جلوتر باهاش بیشتر آشنا میشیم و یاد میگیریم چه کارایی میشه کرد باهاش و یه سیستم کشینگ خیلی جمع و جور هم باهاش مینویسیم.
اگر قبلا با proxy ها آشنا هستید میتونید مستقیم برید سراغ قسمت "پیاده سازی سیستم کش با proxy"
اول یکم در مورد Object ها توی جاواسکریپت بگم. قطعا میدونید. چندتا عملیات خیلی ساده وجود داره. وقتی میخواید یک property رو از داخل object بخونید، وقتی میخواید یه property جدید داخل object ست کنید و وقتی میخواید ببینید یک property توی object وجود داره یا نه و در آخر حذف کردن یک property از داخل object.
خلاصه میشه:
به اینصورت هم نوشته میشن:
const user = { name: 'hesan' }; // get user.name; // hesan // set user.height = 190; // { name: 'hesan', height: 190 } // has 'age' in user; // false 'name' in user; // true // delete delete user.name; // { height: 190 }
تا اینجا هر چیزی گفتم تکراری بود، همه اینا رو میدونیم. حالا ببینیم proxy ها میتونن برامون چیکار کنن.
در واقع Proxy ها یک نوع Object هستند که میان و دور آبجکت هدف شما (این آبجکت میتونه هر چیزی باشه) قرار می گیرن و یه لایه جدید بهش اضافه میکنن. کنترل کردن این proxy کاملا دست خودتونه. میتونید رفتار های خاص بهش بدید، کاری کنید که یه طور دیگه رفتار کنه و خیلی کارای خفنی میشه با این کرد.
اون عملیات هایی که قبلا گفتم یه تعداد عملیات مشخصه، خارج از اینا نیست (البته چندتا دیگه هم هست که من بهش اشاره نکردم).
پراکسی ها ابزار های بسیار قدرتمندی هستند که به کمکشون خیلی کار ها میشه انجام داد و حتی بعضی جا ها میشه بعنوان یک pattern ازش توی معماری اپلیکیشن استفاده کرد. لینک ۲ تا مطلب رو براتون قرار میدم که پیشنهاد میکنم حتما بخونیدشون که عمق توانایی های proxy رو بتونید درک کنید. این مطلب فقط قراره با یک سری از کار های سطحی و اولیه که پراکسی ها برامون میتونن انجام بدن آشنا بشیم.
همونطور که قبلا هم گفتم پراکسی ها دور یک object قرار میگیرن و کاری میکنن رفتار اون object کاستوم بشه و کنترلش بیوفته دست شما. ادبیاتی که برای پراکسی ها استفاده میکنیم چند تا کلمه مهم داره که باهاش آشنا میشیم.
اولین کلمه کلیدی هست: Target. این target همون object هست که میخواید پراکسی دورش قرار بگیره. آبجکت هدفتونه. مثلا:
const user = { name: 'hesan' }; // target object const proxyObject = new Proxy(user); // the proxy object
برای ایجاد یک proxy هم از new Proxy استفاده میشه، ولی اگر الان شما این رو اجرا کنید یه exception میده با این مضمون که "به من handler ندادی"
پس میرسیم به دومین کلمه مهم: Handler. میتونیم رفتار های خاص تعریف کنیم برای آبجکت جدیدمون که اینکار به کمک این handler انجام میشه. handler یه آبجکته که میتونیم توش بگیم وقتی داریم عملیات های مختلف رو روی اون target انجام میدیم میخواید چطور این اتفاق بیوفته و به این شکل هم تعریف میشه:
const user = { name: 'hesan' }; // target object const handler = { // get trap get: (o, property) { return o[property]; } }; const proxyObject = new Proxy(user, handler); // the proxy object
همینطور که میبینید، handler یه آبجکت ساده هست و توش میتونید چندتا متد تعریف کنید که به هر کدوم از اون متد ها میگیم trap. بله.
پس Trap آخرین کلمه ای هست که یاد میگیریم. trap ها انواع مختلفی دارن برای کار های متفاوتی. رایج ترینشون get و set هست. لیست کامل این trap ها رو میتونید اینجا ببینید. دقت کنید که این کلمات تعریف شده هستند و طوری نیست که بتونید خودتون یه متد دلخواه تعریف کنید. من اینجا با ۳ تاشون کار دارم: get و set و has
خب میرسیم به توضیح اینکه این trap ها چی هستند. برای فهم بهترش این مثال رو ببینید:
user.name
وقتی شما این رو مینویسید در واقع دارید یه property از آبجکت user رو میخونید، اگر این user یک proxy باشه، متد get داخل handler رو داره صدا میزنه و به کمک اون اطلاعات property رو بهتون میده.
اینجا که کنترل دست شماست! میخواید مثل مثال بالا فقط اون property رو برگردونید یا میخواید کار دیگه هم انجام بدید؟
همین داستان برای set و has به این شکل اتفاق میوفته:
user.name = 'hesan'; // set 'name' in user; // has
با نوشتن هر کدوم از موارد بالا متد هایی که جلوش کامنت کردم صدا زده میشن. این کد رو از اینجا کپی کنید و اجراش کنید:
خب اگه این کد رو اجرا کنید، یه پراکسی تخس درست کردیم که هر پراپرتی از توش بخوایم بخونیم میگه undefined هست و هر مقداری هم توش بخوایم ست کنیم بر عکسش رو ست میکنه و اگرم بخوایم ببینیم یک پراپرتی توش وجود داره میگه false.
هر کدوم تابع های trap رو میتونید به میل خودتون بنویسید، من اینجا برای اینکه نشون بدم میشه هرکاری کرد کدش رو این شکلی نوشتم ولی خیلی کار های دیگه میشه کرد.
امیدوارم تا اینجا با خود proxy آشنا شده باشید و قابلیت هایی که بهمون میده رو هم فهمیده باشید، میریم سراغ کاربردش تو دنیای واقعی.
قبل اینکه بریم سراغ مثال cache باید بگم که از proxy ها خیلی جاها استفاده میشه. از نمونه هاش میتونم بگم برای سیستم کشینگ، validation و حتی مثلا هندل کردن event ها (که مثلا React ازش استفاده میکنه).
مثالی که من اینجا مینویسم خیلی ساده و الهام گرفته شده از مطالبی هست که قبلا خوندم، پس میدونم که ضعف هایی داره.
این سیستم از این قراره که مثلا اگر شما دنبال دیتای یک user خاص هستید، اون رو از داخل object فراخوانی میکنید. ولی این آبجکت ما یک Proxy هست که اگر دیتا اون یوزر رو داشته باشه از سیستم کش بهتون میده و اگر نداشته باشه یه درخواست ارسال میکنه به سرور تا دیتاش رو بگیره و از اون به بعد اون یوزر با اون id داخل آبجکت cache میشه دیگه تماسی با سرور گرفته نمیشه. منطق این درخواست به سرور رو هم داخل get از handler های این پراکسی مینویسیم.
برای اینکه مطلب طولانی نشه، من کدش رو قرار میدم و خط به خط توضیح میدم که چه اتفاقی داره میوفته.
خب این کل کار هست. خط به خط حالا توضیح میدم که چه خبره.
خب ببینیم تو این مثال چه خبره:
داخل handlers فقط از یه دونه set trap استفاده کردم، target که اشاره میکنه به همون آبجکت target و property همون مقداری هست که میخوایم ست کنیم. اینجا قبل از اینکه چیزی رو ست کنم بررسی کردم که اگر email میخواست ست بشه قبلش ببین آیا با این pattern که بهش گفتم match میشه یا نه. اگر match شد که داخل target قرار میگیره و مشکلی نیست. ولی اگر نشد یه exception میده و میگه که فرمت ایمیلی که دادی درست نیست.
این یه خلاصه خیلی کوچیکی بود که من با سواد نداشته ام، سعی کردم یکم در مورد قابلیت هایی که Proxy ها بهمون میدن و خودم بلدم صحبت کنم. امیدوارم شما بتونید کار های خیلی خفن تری باهاش انجام بدید.
دمتون گرم که تا اینجای مطلب رو خوندید، اگر دوست داشتید میتونید از طریق لینکدین باهام در ارتباط باشید!
موفق باشید!