- Lazy Initialization چیست؟
Lazy Initialization در برنامه نویسی به معنای به تعویق انداختن ساخت یک Object تا لحظه ی استفاده از آن می باشد که جهت افزایش بازدهی نرم افزار و استفاده ی بهینه از حافظه ی RAM به کار برده می شود. این تکنیک اغلب در دو سناریو استفاده می شود :
- هنگامی که ساخت یک Object پرهزینه بوده (برای مثال مقدار حافظه ی زیادی اشغال می کند و یا بار زیادی برای CPU به همراه دارد) و در عین حال ممکن است هیچ گاه در جریان برنامه مورد استفاده قرار نگیرد.
- هنگامی که ساخت یک Object پرهزینه بوده و تا زمان تکمیل شدن ساخت Object پرهزینه ی دیگری، به تعویق انداخته می شود.
در .Net Framework 4 سه کلاس به نام های Lazy<T> ،ThreadLocal<T> و LazyInitializer برای پیاده سازی تکنیک Lazy Initialization در سناریوهای مختلف وجود دارد. در این مقاله قصد داریم به بررسی کلاس Lazy<T> بپردازیم.
- معرفی کلاس Lazy<T>
برای پیاده سازی تکنیک Lazy Initialization بر روی یک Object می توانید آن را با استفاده از کلاس جنریک Lazy<T> تعریف نمایید. برای مثال :
1 |
Lazy<RegistrationService> registrationService = new Lazy<RegistrationService>(); |
به این ترتیب Object مورد نظر شما (در مثال فوق registrationService) اولین باری که مورد استفاده قرار گیرد، مقدار دهی شده و حافظه میگیرد. کلاس های Lazy دارای دو Property به نام های IsValueCreated و Value می باشند. مشخصه ی Value همان Object مورد نظر شما می باشد که در اولین دسترسی مقداردهی می شود. مشخصه ی IsValueCreated نیز یک مقدار Boolean می باشد که مشخص میکند که Object مورد نظر مقدار دهی شده است یا خیر :
1 2 3 4 5 6 7 |
Lazy<RegistrationService> registrationService = new Lazy<RegistrationService>(); isCreated = registrationService.IsValueCreated; //Returns false registrationService.Value.Register(user); isCreated = registrationService.IsValueCreated; //Returns true |
نکته : در حالت پیش فرض کلاس Lazy از متد Activator.CreateInstance برای ساخت Object ها استفاده میکند. به همین دلیل در صورت عدم وجود Constructor عمومی بدون پارامتر در کلاس فوق، با Exception مواجه خواهید شد. برای رفع این مشکل می توانید با ارسال Delegate به کلاس Lazy، نحوه ی ساخت Object مورد نظر را معرفی کنید :
1 2 3 4 5 6 7 8 9 10 11 |
public class RegistrationService { public RegistrationService(bool sendNotify) { } . . . Lazy<RegistrationService> service = new Lazy<RegistrationService>(() => new RegistrationService(true)); |
همچنین این کلاس Thread-Safe بوده و در سناریوهای Multi-Thread نیز بدون مشکل قابل استفاده می باشد.
ممنون هادی جان
مفید بود. من هر روز به سایتت سر میزنم. تا اینجا که خیلی خوب بوده!
موفق باشی!
ممنونم رضا جان، تشکر
خیلی خوشحالم که مطالب رو میخونی
عالی و زیبا … و بسیار سبک و سریع
بسیار ممنونم
خواهش میکنم، لطف دارید
سلام
از شما بابت مطالبتان متشکرم.
راستی اون دو شکل دیگر را هم توضیح می دهید؟
سلام
خواهش میکنم
بله حتما در آینده به روش های دیگر برای پیاده سازی Lazy Initialization هم خواهم پرداخت.
سلامدوست عزیز
من بعد از چندین ماه و بطور اتفاقی به سایت شما سر زدم و می بینم که یکجورایی غیرفعال شده و خیلی وقته دیگه مطلب جدیدی در دسترس کاربران سایت قرار داده نشده!!
انشاءالله که هرچه زودتر آموزشها تون استارت مجدد بخوره و کاربران بتونن از مطالب مفید شما استفاده ببرند.
موفق باشید.
سلام جناب علی اکبری عزیز
ممنون از لطف شما
بله متاسفانه چند وقتی هست که به علت مشغله کاری زیاد، فرصتی برای نوشتن مطلب جدید ندارم.
امیدوارم در آینده ی نزدیک زمان آزاد داشته باشم تا بتونم مثل قبل به نوشتن ادامه بدم.
سپاس فراوان
با دورد .. کاش این موضوع رو به صورت تصویری تدریس میکرید بنظرم خیلی مطلب گنگ و پیچیده ای ..
با سلام
متاسفانه زمان آزاد کافی برای درست کردن آموزش تصویری ندارم.
می توانید از ویدیوهای موجود در Pluralsight استفاده کنید. اگر علاقه مند بودید بفرمایید تا ویدیوهای مرتبط رو بهتون معرفی کنم.
موفق باشید
سلام ممنون،
خب اینجوری که در تمامی مقالات و آموزش ها از فواید مثبت این کلاس یاد شده….
چه اتفاقی میوفته اگه همه چی با این کلاس ایجاد بشه آیا؟!
سلام.
استفاده از Lazy در هر جایی فایده ندارد و الزاما مفید نیست (مگر در حالت هایی که در مقاله عرض کردم) و ممکن است باعث ناخوانی کد و افزایش پیچیدگی کد شود.
سلام ممنون از مقالات خوبتون . اگه امکان داره درباه شی گرایی هم مقاله بزارید سپاس.
سلام، خیلی ممنونم جناب طلایی. انشالا در فرصت مناسب در مورد شی گرایی هم خواهم نوشت