الگویِ طراحیِ Object Pool (جاوا و کاتلین)

یک جامدادی رو در نظر بگیرید ، وقتی شما به یک مداد نیاز دارید نمی‌رید هر سری از مغازه یه مداد جدید بخرید بلکه قبلا یک سری مداد رو تهیه می‌کنید و بعد ازشون استفاده می‌کنید ، اگه دوستاتون هم مداد بخوان می‌تونید از جامدادیتون بهشون مداد بدید ، این تقریبا همون Object Pool میشه !

جا‌مدادی حکم مجموعه‌ای از اشیا (مداد) را دارد
جا‌مدادی حکم مجموعه‌ای از اشیا (مداد) را دارد

ترجمه Pool در لغت به معنی "مجموعه" هست ، یعنی مجموعه‌ای از اشیا ، در مثال بالا خریدِ یک مداد از مغازه کاری هزینه بره ، هم از نظر قیمت هم از نظر زمان و ... ، ما در Object Pool مجموعه‌ای از اشیا رو که هزینه ساختشون زیاده رو نگه‌داری می‌کنیم و هر زمانی که بهشون نیاز داشته باشیم از Pool یک شئ قرض می‌گیریم و وقتی هم کارمون تموم شد اون شئ رو به Pool برمی‌گردونیم ، این الگو جزء دسته‌ی Creational طبقه بندی میشه .

صورت مساله

مجموعه‌ای از Computerها رو داریم و بین کارمندان پخششون می‌کنیم ، برای این حالت با Object Pool مدل‌سازی می‌کنیم . برای این کار اول یک کلاسِ Abstract به نام ObjectPool ایجاد می‌کنیم ، چند متد را در این کلاس باید پیاده‌سازی و چند متد را صرفا تعریف کنیم :

create

این متد صرفا تعریف می‌شود و در کلاسی که از ObjectPool متشق شده باشد پیاده‌سازی می‌شود ، وظیفه آن ایجاد یک شئِ جدید برای ObjectPool است

validate

صرفا تعریف می‌شود و خروجی آن Boolean است که یک شئ را ورودی می‌گیرد ، در پیاده‌سازی در کلاسِ فرزند به این می‌پردازد که یک شئ valid هست یا خیر

expire

در ObjectPool هر شئ یک بازه‌زمانی دارد ، اگر تاریخ انقضایِ شئ بگذرد باید منقضی شود ، این تابع صرفا تعریف می‌شود و در کلاسِ فرزند پیاده سازی می‌شود

checkOut

این تابع در خودِ کلاسِ ObjectPool پیاده‌سازی می‌شود و خروجی از جنسِ شئ برمی‌گرداند ، وظیفه این تابع این است که از لیستی (که ما در کد به صورت یک Map از شئ و Long در نظر گرفتیم که کلید همان شئ است و value همان Long و این Value زمانِ ایجادِ شئ است که بعدا برای تاریخ انقضا بررسی می‌شود) به نام unLocked یک شئ بردارد و به لیستی به نام lock اضافه کند و آن را برگرداند ، در این بین باید بررسی کند اگر تاریخ انقضایِ شئ گذشته باشد یا valid نبود آن‌را expire کند (که در این صورت یک شئ create کرده و برمی‌گرداند) ، این تابع Synchronized است (برای Thread safe بودن) .

checkIn

این تابع در خودِ ObjectPool پیاده‌سازی می‌شود و وظیفه آن این است که یک شئ به عنوان ورودی بگیرد و برعکس checkOut را انجام دهد ، یعنی از locked به unLocked منتقل کند ، در این بین زمانِ شئ را هم بروز می‌کند ، این تابع نیز Synchronized است .

پیاده‌سازیِ این کلاس را در کدِ زیر می‌بینیم :

https://gist.github.com/sasssass/2e73ba83a7b2fc61df969fd51fa58685

حالا شئ Computer و ComputerObjectPool را پیاده‌سازی می‌کنیم (برای منطقی شدن مثالمون فرض کردیم Computer یک متغیر به اسم pluggedIn داره که اگه قرار باشه expire بشه اون رو false می‌گذاریم که یعنی از برق کشیده شده) :

https://gist.github.com/sasssass/abbcff3d7b7125c6a45fe5d1c76ef63f

و در آخر در هرجای برنامه که نیاز داشتیم از اون می‌تونیم استفاده کنیم :

https://gist.github.com/sasssass/cb61dd75e7733e254b2fc63db28e9286
نکته : بهتره اون Instance ای که از ObjectPool می‌گیرید رو به صورت Singleton در بیارید

باقی مقالات در مورد الگوی‌های طراحی رو در این مقاله بخونید .

من رو در لینکدین و اینستاگرام دنبال کنید ???

اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???