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

من همیشه در سری مقالاتی که از دیزاین پترن ها می‌ذارم ، اولِ کار معنی لغویِ اون پترن رو میگم که شما بهتر متوجه عملکردش بشید ، خب حالا Flyweight یعنی چی ؟ یعنی "سبک وزن" (از دو کلمه fly به معنی مگس و weight به معنی وزن ، یعنی وزنش در حد یه مگسه) ، خب پس ما می‌خوایم از وزن یک چیزی کم کنیم و اون رو سبک وزن کنیم ولی چیو ؟ Memory رو ! این کلِ کاریه که Flyweight قراره انجام بده ، ولی چطوری ؟

وزن مگس و پشه چقدره ؟ عملا هیچی !
وزن مگس و پشه چقدره ؟ عملا هیچی !

این الگو جزء دسته Structuralها حساب میشه و شبیه Object pool هست (که به تفاوت‌هاش اشاره می‌کنیم) و ما مثل Object pool دوباره یک Map می‌سازیم ولی نه به شکلی که در Object pool ازش استفاده می‌کنیم ، من در مقالاتی که دیدم خیلی خوب این مساله رو توضیح نمیدن و مثال‌هایی که زدن دقیقا عین Object pool میشه که صحیح نیست ، یک شئ در Flyweight دو نوع عنصر داره ، ذاتی (intrinsic) و بیرونی (extrinsic) ، متغیرهای ذاتی برای یک دسته از اشیای یکی هستند ، مثلا فرض کنید کلاس Computer رو داریم ، این کلاس متغیر سیستم عامل رو داره که یا Linux هست یا Windows یا Mac و یک متغیر هم برای Ram داره که می‌تونه هر عددی باشه ، سیستم عامل رو متغیر ذاتی و Ram رو بیرونی در نظر می‌گیریم . حالا فرض کنیم 2000 تا Computer نیاز داریم پس باید 2000 تا جا برای Windows و 2000 تا جا برای Ram هم در حافظه داشته باشیم که مقدارشون رو ذخیره کنیم ، ولی ما نمیخوایم اینطوری حافظه هدر بره ، پس اون متغیری که ذاتی هست رو به صورت اشتراکی بین Computer ها پخش می‌کنیم که کلاس 3 تا جا براش استفاده بشه . بیایید همین مثال رو به صورت کدی در بیاریم که بهتر متوجه بشیم :

اول از همه میاییم دو کلاسِ OS و Computer و یک Enum به اسم OSType ایجاد می‌کنیم ، Computer یک Ram و یک OS داره که OS باید به صورت اشتراکی بین Computerها پخش بشه :

https://gist.github.com/sasssass/9b19bf8b126268f7da2699a4f146f381

حالا باید یک Singleton به اسم OSSharedVars درست کنیم که وظیفه‌اش ایجاد یک Map از OS هاست ، این Map در بدترین حالت 3 عضو خواهد داشت و این اعضا به صورت اشتراکی بین Computerها پخش میشن :

https://gist.github.com/sasssass/88c94786b53082b6034576d80933eeae

بقیه کار مشخصه ، ما با استفاده از OSSharedVars در حین ساختن Computerها قسمت OS رو اشتراکی قرار می‌دیم (یعنی کلا در حافظه 3 قسمت برای OS درنظر گرفته شده) و قسمت Ram رو به ازای هر Computer . مثلا لیستی از Computerها رو این طوری می‌سازیم :

https://gist.github.com/sasssass/15b1b81caf63005082b82b30efaa3e8e

الان ما 1024 تا ویندوزی ، 1024 تا لینوکسی و 1024 تا مک داریم ، اگه این قسمت رو دیباگ بگیریم می‌بینیم که قسمت OS دارای حافظه مشترکی شدند :

تا الان باید تفاوت‌های این الگو رو با Object pool فهمیده باشید ولی من همون‌طور که در ابتدا گفتم تفاوت‌ها رو لیست می‌کنیم :

  • ما اینجا هدفمون ساختِ شئ نبوده پس برای همین جزء Creationalها حسابش نکردیم و گفتیم Structural
  • در Object pool ما وقتی شئ رو استفاده می‌کنیم اون رو از pool خارج می‌کنیم ولی اینجا چون هدف ساخت شئ نیست بلکه اشتراک گذاری اشیا هست پس از pool خارج نمیشه
  • در اینجا ما OSSharedVars رو به صورت Singleton در آوردیم که کلِ App ازش استفاده کنه ولی در Object pool قر قسمت Object pool رو ایجاد می‌کنیم

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

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

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