اوکی، خب حالا که دو نوع دیگه از دیپندِنسی اینجِکشِن (dependency injection) رو دیدیم،
بریم سراغ نوع سوم، که اینتِرفِیس اینجکشن هست.
خب، این کار شامل ارائه دیپندِنسی‌ها (dependencies) از طریق اینتِرفِیسی (interface) هست که اون کلاس، پیاده‌سازیش می‌کنه.
پس خود اینتِرفِیس متدها رو برای سِت کردن دیپندِنسی‌ها تعریف می‌کنه.
بسیار خب.
خب بیاید بریم جلو و یک public interface ایجاد کنیم که من اسمش رو می‌ذارم IToolUser، اوکی؟
چه اسم باحالی.
می‌بینید که اینجا حرف I بزرگه.
حرف دوم هم همین‌طور.
پس می‌گیم که هر وقت می‌خواید از یک Tool User مثل سازنده (Builder) استفاده کنید، باید چکش (Hammer) رو سِت کنید.
پس می‌گیم:
"یه چکش به من بده" و باید اره (Saw) رو هم سِت کنید.
و می‌گیم: "یه اره به من بده".
خب، چکش هنوز کارهایی رو انجام می‌ده.
اره هم فقط داره استفاده می‌شه، اما سازنده (Builder) هست که در اون تغییر ایجاد می‌شه.
سازنده حالا یک IToolUser هست، پس اون حالا یک Tool Userه، به این معنی که باید چکش رو سِت کنه،
و باید اره رو هم سِت کنه قبل از اینکه بتونه خونه رو بسازه.
یا حداقل متدهای اون باید وجود داشته باشند.
خب می‌تونیم برگردیم به اینکه این‌ها فیلدهای (fields) خصوصی (private) باشند.
پس، private hammer underscore hammer.
و بیاید یک underscore اضافه کنیم چون خصوصی هست و private saw underscore saw.
خب مشخصه وقتی از چکش استفاده می‌کنیم، باید بگیم hammer use.
و وقتی از اره استفاده می‌کنیم، باید بگیم underscore saw dot use.
پس حالا ما همچنان باید اون دو تا متدی رو پیاده‌سازی کنیم که در اون‌ها چکش و اره رو سِت می‌کنیم.
پس بریم روشون هاور (hover) کنیم و راه‌حل‌های بالقوه رو ببینیم.
و بگیم "پیاده‌سازی اینترفیس" (implement the interface).
و کاری که انجام می‌ده اینه که اون دو تا متد رو برامون ایجاد می‌کنه.
پس set hammer، که در اون به یک چکش نیاز داریم و کاری که قراره انجام بدیم اینه که اون چکش رو برداریم
و داخل underscore hammer ذخیره‌اش کنیم.
پس چیزی که داریم می‌گیم اینه که چکشی رو که به من می‌دهید، به عنوان چکشِ اون سازنده، برای استفاده سِت کنید.
پس سازنده هر وقت set hammer سِت بشه، یک چکش می‌گیره.
و بعد همین کار رو با اره انجام می‌دیم.
پس هر وقت set saw استفاده می‌شه، فقط اره رو به من بده.
بنابراین حالا به جای استفاده از سِتِرها (setters)، داریم از اینتِرفِیس‌ها استفاده می‌کنیم.
البته می‌تونید اون‌ها رو هم سِتِر صدا کنید، اما داریم با یک معماری پیچیده‌تر ازش استفاده می‌کنیم.
این به ما اجازه می‌ده حالا Tool Userهای بیشتری ایجاد کنیم.
پس فقط سازنده (Builder) نیست که می‌تونه از این ابزارها استفاده کنه، بلکه شخص دیگه‌ای هم می‌تونه، مثل
سازنده‌مون و شاید خانه‌ساز، یا هر چیز دیگه‌ای.
اما بعدش یک مکانیک (mechanic) هم داریم، اوکی؟
و مکانیک یک سازنده نیست، اما شاید هنوز هم بتونه از اره و چکش استفاده کنه.
و در اون صورت، ما همچنان باید اون‌ها رو بهشون بدیم، پس می‌تونیم از set saw برای سِت کردن اره استفاده کنیم.
و می‌تونیم از builder set hammer برای سِت کردن چکش استفاده کنیم.
پس اینجا dot set hammer و چکش رو پاس (pass) می‌دیم.
و کدوم اره و چکشی رو داریم پاس می‌دیم؟
بذارید در واقع ترتیبی رو که قبلاً داشتیم حفظ کنم.
خب ما چکشی رو که اینجا ایجاد کردیم پاس می‌دیم، یعنی دیپندِنسی.
و همین‌طور برای اره.
پس ما اون دو تا رو به set hammer و set saw پاس می‌دیم.
و حالا می‌تونیم از اون‌ها استفاده کنیم.
و می‌بینیم "میخ زدن با چکش"، "بریدن چوب با اره"، "خانه ساخته شد".
پس می‌بینید که روش‌های مختلف زیادی وجود داره برای اینکه دیپندِنسی اینجکشن رو اجرا کنید، اوکی؟
خب حالا بیاید سعی کنیم این رو کمی بهتر درک کنیم.
خب، اینتِرفِیس اینجکشن، در این مورد، کلاس سازنده (builder) اینتِرفِیس IToolUser رو پیاده‌سازی می‌کنه که
متدهایی رو برای سِت کردن دیپندِنسی‌هاش تعریف می‌کنه.
مزیت این کار اینه که به ما انعطاف‌پذیری می‌ده.
پس دیپندِنسی‌ها از طریق متدهای اینتِرفِیس تزریق (inject) می‌شن، و به کلاس اجازه می‌دن دیپندِنسی‌هاش رو
از یک منبع خارجی دریافت کنه.
حالا بیاید سه مثال رو که داشتیم با هم مقایسه کنیم.
خب ما اینجکشن‌های مختلف رو داشتیم، درسته؟
پس بیاید متدهای اینجکشن رو مقایسه کنیم.
ما Constructor Injection رو داریم.
مزایای اون اینه که تضمین می‌کنه.
همه دیپندِنسی‌ها در زمان ساخت آبجکت (object) ارائه می‌شن، که این خیلی خوبه.
اما معایبی هم داره.
دیپندِنسی‌ها بعد از ساخت آبجکت قابل تغییر نیستند.
بعد Setter Injection رو داریم.
مزیتش اینه که اجازه می‌ده دیپندِنسی‌ها بعد از ساخت آبجکت تغییر کنند.
معایبش اینه که.
ممکنه دیپندِنسی‌ها در زمان ساخت آبجکت سِت نشوند، که منجر به استثناهای احتمالی Null Reference می‌شه،
همونطور که دیدیم.
درسته؟
شروع به اجرا کردیم و دیدیم که کِرَش (crash) کرد چون دیپندِنسی‌های مختلفی رو که مورد نیاز بودند، سِت نکرده بودیم.
بله.
بعد Interface Injection رو داریم که همین الان تمومش کردیم.
مزایاش اینه که یک قرارداد واضح رو برای.
برای تزریق دیپندِنسی‌ها از طریق اینتِرفِیس‌ها ارائه می‌ده.
پس تمام مزایای اینتِرفِیس‌ها اینجا وجود دارند.
اما معایبش اینه که نیاز به تعریف اینتِرفِیس‌های اضافی برای سِت کردن دیپندِنسی‌ها داره.
پس نتیجه‌گیری: با استفاده از مثال سازنده (Builder)، سه روش دیپندِنسی اینجکشن رو نشون دادیم.
Constructor Injection که در اون دیپندِنسی‌ها از طریق کانسترَکتور (constructor) ارائه می‌شن، Setter Injection که در اون
دیپندِنسی‌ها از طریق پراپرتی‌ها (properties) یا متدهای عمومی (public methods) سِت می‌شن، و Interface Injection که در اون دیپندِنسی‌ها
از طریق متدهای تعریف شده در یک اینتِرفِیس تزریق می‌شن.
هر روشی مزایا و معایب خاص خودش رو داره و درکِ
این‌ها می‌تونه بهتون کمک کنه بهترین رویکرد رو برای مورد استفاده خاص خودتون انتخاب کنید.
با استفاده از دیپندِنسی اینجکشن، می‌تونید کدهای ماژولارتر، انعطاف‌پذیرتر و قابل تست‌تری ایجاد کنید.