Design Patterns و Dependency Injection
بسم الله الرحمن الرحیم
آموزش dependency injection
امروزه تمرکز بیشتری از گذشته بر روی استفاده مجدد از کامپوننت های موجود و ارتباط بین کامپوننت های مستقل به شکل یک معماری منسجم مطرح است.
اما این ارتباط در انجام وابستگی می تواند به دلیل اندازه نرم افزار و افزایش پیچیدگی باعث ایجاد ترس شود. یک راه برای کاهش تکثیر وابستگی استفاده از تزریق وابستگی یا به اصطلاح Dependency Injection که به صورت مختصر (DI) است که اجازه می دهد یک شی را به یک کلاس تزریق کنید بجای اینکه در کلاس خود شی ایجاد شود، تکثیر وابستگی با تزریق بسیار متفاوت است وقتی یک شی را می سازید تکثیر می کند اما تزریق اینطور نیست کمی اگر صبور باشید آن را نیز فرا خواهید گرفت.
استفاده از یک کلاس کارخانه یکی از راه حل های موجود است. هنگامی که یک جزء، (Component) یک نمونه خصوصی از کلاس دیگر را می سازد، آن مقدار دهی منطقی می شود درون آن جزء، این مقدار دهی منطقی بندرت خارج از ساخت جزء قابل استفاده است بنابراین برای هر کلاسی که نیاز به این نمونه دارد باید فرایند ساخت تکرار گردد (اضافه کردن سربار به سیستم قابل توجه دوستان طراح وب).
برای مثال اگر کلاس Foo یک شی از کلاس Bar بسازد و نمونه ای از کلاس Bar نیاز به چندین مقدار دهی داشته باشد و برای هر نمونه متفاوت باشد، کلاس های دیگر که نمونه ای از کلاس Bar را می سازند مجبورند نمونه ای با مقداری یکسان دوباره بسازند! (توضیح دادن آن کمی پیچیده است انشالله در مثال ها بیشتر متوجه خواهید شد.)
توسعه دهندگان کارهای تکراری و خسته کننده ای دارند و هنوز بیشتر توسعه دهندگان کارهایی شبیه رفع وابستگی و ساخت اشیا را به صورت دستی انجام می دهند. وضوح وابستگی می تواند حل کردن وابستگی های یک شی یا نوع را توصیف کند.
تزریق وابستگی از سوی دیگر هدفش کاستن مقدار رابطه و زیرساخت های کدی است که شما می نویسید است.
Containers یک لایه از abstraction که خانه ای برای اجزاء است فراهم می کنند.
DI containers به طور خاص نوعی از وابستگی مستحکم را کاهش می دهد
من فقط توصیف می کنم این را با عمومی کلاس factory که نمونه ای از نمونه کلاس است
این اشیاء به وسیله container تنظیم می شوند و منطق ساخته شده اجازه می دهد که مجددا بتوان به صورت گسترده از آن استفاده کرد.
قبل از وارد شدن به DI containers، اجازه دهید هسته الگوی بکار رفته در DI containers را که Abstract Factory pattern نام دارد بازبینی کنیم.
در الگوی طراحی (Design Patterns) ارائه شده توسط Addison-Wesley در سال 1995، نویسندگانی چون Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides منظور خود را از Abstract Factory pattern به این صورت بیان می کنند:
ساخت و مقداردهی یک مجموعه از اشیاء مرتبط بدون تغییر در ساختار واقعی آنها.
با استفاده از Abstract Factory pattern در برنامه خود، شما می توانید abstract classes را تعریف کنید تا شی هایی با که دارای رابطه با یکدیگر هستند را ایجاد نمایید. شما با کنترل بر وابستگی ها و حالت های مجاز بر اشیاء به وسیله کپسوله سازی نمونه سازی و ساخت منطقی را حفظ می کنید.
غالبا اشیاء نیازمند هستند معمولا در یک روش هماهنگ شده نمونه سازی شوند چون می بایست وابستگی ها یا سایر نیازمندی ها تعیین شود.
طبیعتا خیلی صریح و خوب توضیح ندادم به همین دلیل مثالی را بررسی می کنیم تا انشالله به مطلب واقف شوید.
مثال:
هنگامی که شما یک نمونه از System.Xml.XmlValidatingReader ایجاد می کنید، یک شی XmlSchemaCollection غالبا تجمیع شده است با شماهای(Schema) مناسب برای اعتبارسنجی شی XmlValidatingReader در زمانی میخواهید از آن استفاده کنید.
این مثال تنها برای ساخت فقط یک نمونه از کلاس نیست، بلکه آن را بعد از ساخت و قبل از استفاده پیکربندی می کند.
نوع دیگری از factory pattern، فکتوری متد است (factory method).
factory method به سادگی یک متد است که معمولا به صورت استاتیک تعریف می شود و تنها هدف آن بازگشت یک نمونه از کلاس است.
گاهی اوقات در تسهیل polymorphism یک پرچم یا همان flag به factory method انتقال داده می شود تا بوسیله آن تعیین شود که کدام اینترفیس یا زیر کلاس باید برای پیاده سازی بازگشت داده شود.
برای مثال، متد Create در WebRequest ایجاد می کند نمونه ای از هر دو نوع string or Uri ایجاد می کند و یک شی جدید از کلاس مشتق شده از WebRequest را بازیابی می کند.
از این لحظه به بعد، به آسانی از کلمه factories به هر دو معنی Abstract Factory pattern و همچنین factory method implementation استفاده می کنیم.
ادامه دارد....