گرچه برنامه نویسی شی گرا انعطاف پذیری زیادی به همراه دارد ولی چالشهایی نیز به دنبال دارد. چرا که همه چیز را میخواهیم به صورت یک شی یا Object مدل کنیم و بنابر این مقادیر زیادی اسناد و کاراکترهایشان را در قالب شی مجبوریم ذخیره کنیم. این گونه برنامه ها باعث کلی overhead در زمان runtime میشوند.
هدف: این الگو باعث کاهش هزینه ذخیره سازی برای تعداد زیادی از اشیا میشود به این گونه که به ما اجازه میده بجای ساخت تعداد زیادی از اشیا، از بخشهای مشترک اونها فاکتور بگیریم و تنها چند شی ایجاد کنیم و در بخشهای مختلف برنامه به کار بگیریم. این الگو از همه مهمتر انعطاف برنامه نویسی شی گرا را حفظ میکند. بدر مجموع، این الگو اجازه استفاده اشتراکی از اشیا را به ما میدهد.
مثال: نرم افزار طراحی داخلی منازل
کلاسهای موجود: انواع کاشی از قبیل سرامیک – سنگ – گرانیت
و این کاشیها میتوانند در سرویسها ، آشپزخانه یا حتی حیاط خانه استفاده شوند.
نرم افزار به ما اجازه میده هر نوع کاشی خواستی برداری و هر جا نیاز داشتی استفاده کنی.
مساله: نرم افزار برای رسم هر کاشی یک شی از اون می سازه و بعد ترسیم میکنه.
فرض کنید برای طراحی یک آپارتمان بزرگ نیاز به مثلا صد هزار کاشی از 3 نوع مختلف داشته باشید. در این صورت نرم افزار باید صد هزار تا شی از اون نوع کاشیها ایجاد کنه و در حافظه نگهداری کنه.
در نرم افزار یک اینترفیس پایه بنام ITile داریم که متدی بنام Draw در اون اعلان شده
و کلاسهایی داریم که اون اینترفیس رو implement میکنه و متد Draw رو برای خودشون بازنویسی میکنن.
متد Draw از طریق متد FillRectangle داخل کلاس Graphics ، این کاشیها را بر اساس داده های ابعاد و رنگ ترسیم میکند.
راه حل: بهتره برای کاشیهای از یک نوع فقط یک شی ایجاد بشه و فیلدهای خارجی یا Extrinsic را به متدهای شی پاس بدیم تا کار ترسیم رو انجام بدن. برای فیلدهای داخلی یا intrinsic هم هنگام ایجاد شی جدید از هر نوع اونها رو مقداردهی میکنم.
بطور خلاصه 2 نوع State در این الگو داریم.
- IntrinsicState: داخل شی fw نگهداری میشن. و ربطی به کانتکست ندارن و بنابراین Shareable هست.
- ExtrinsicState: بر اساس شی تفاوت میکند ولی داخل شی fw نگهداری نمیشود. این وضعیت برای شی از طریق پارامترها مهیا میشود.
تشخیص و جدا نمودن این وضعیتها کلید پیاده سازی این الگو و رفع مشکل است.
شی اشتراکی را نیز flyweight مینامیم.
با بیرون کردن وضعیت خارجی شی، در مصرف حافظه صرفه جویی میکنیم.
چالش : از کجا مطمین بشیم که هر کی برای خودش شی FlyWeight نسازه؟؟
راه حل: استفاده از FlyWeightFactory است که کار ایجاد و مدیریت FlyWeight ها را به عهده دارد.
وقتی کلاینت درخواست ایجاد شی FlyWeightمیده، factory میره بررسی میکنه اگه شی موجود بود برمیگردونه و گرنه یه دونه جدید میسازه.
توجه مهم: این الگو در جایی که نیاز به ذخیره برخی مقادیر وضعیتهای شی نداریم (مثلا ابعاد کاشی) بکار میاد. مطمینا چنانچه شما برای هر شی بطور خاص بخواهید بعدا به همون مقادیر وضعیتها دسترسی داشته باشید دیگه نمتوانید از این الگو بهره ببرید.
برچسب:
نویسنده: امیر کریمی