تشبیهی برای درک بهتر Dependency Injection

جمعه 6 آذر 1394

در سایت ما مقاله های بسیاری وجود دارند که جزییات پیاده سازی انواع تزریق وابستگی ها(DI) در زمینه #C را توضیح داده اند. در این مقاله هم مورد جدیدی وجود ندارد اما یک قیاس یا تشبیه به شما کمک می کند تا مزایای DI را بهتر درک کنید. همیشه روشن نیست که DI چگونه بازدهی کدنویسی شما را بالا می برد. امیدواریم این مقاله مزایای تزریق وابستگی ها را به خوبی نشان دهد.

تشبیهی برای درک بهتر Dependency Injection

ابتدا با کلاس زیر شروع می کنیم:

public class CordlessDrill  
{  
    public void Drill()  
    {  
        var drillBit = new DrillBit();  
        drillBit.Turn();  
    }  
} 

 در اینجا یک دریل(drill) بی سیم تعریف می کنیم که قابلیت دریل کردن اشیاء را دارد، اما بدیهی است که انجام این کار به خود drill نیز بستگی دارد. بنابراین، یک نمونه(instance) از drillBitرا ایجاد می کنیم و با فراخوانی Turn( ) متدروی شیئ ایجاد شده، drill(دریل) را روشن می کنیم. این نوع کلاس ها را "tightly-coupled" یا اتصال محکم می نامند که کلاس drill به طور مستقیم به ذات خود شیئ DrillBit بستگی دارد. تا اینجا همه چیز خوب است، Drill یه کار مشخص را انجام می دهد.

اما حالا  نیاز داریم که این شیئ یک کار متفاوت انجام دهد: مثلا نیاز داریم که یک اره چوبی داشته باشیم. پس به نظر می رسد، کلاسی که در اینجا نوشتیم برای ما بی فایده است، بنابراین کلاس دیگری ایجاد می کنیم یعنی ابزار دیگری برای انجام این کار خاص ایجاد می کنیم:

    public class CordlessSaw  
    {  
        public void Saw()  
        {  
            var sawBlade = new SawBlade();  
            sawBlade.Saw();  
        }  
    } 

توسط کد بالا مجدد یک کلاس tightly-coupled با کلاس دیگر طراحی می کنیم که کار مشخص مورد نظر ما را انجام دهد.

تا اینجا ابزار کافی برای انجام هر دو کار داریم، اما برای کار جدید دیگر، به موانع جدیدی برخورد می کنیم  و نیازمندی های آن نیز جدید است برای همین دوباره به کلاس های جدیدی نیاز داریم. این کار برای نوشتن کلاس های "cordless" (کلاس هایی برای دریل های بی سیم و قابل حمل) ناکارآمد است. زمانی که در واقع آنها برخی قابلیت های رایج را به اشتراک می گذارند زمان آن است که تزریق وابستگی انجام گیرد.

اگر ما جزییات ابزار وابستگی را نادیده بگیریم (نوع پیاده سازی ) -برای مثال اینکه آیا این شیئ یک اره است یا یک دریل- می توانیم بر روی این واقیت تمرکز کنیم که برخی ابزارها باید اضافه شوند تا از قدرت آنها استفاده شود این فقط یک کار است. این کار به ما اجازه می دهد تا فقط یک پیوست به عنوان ضمیمه تعریف کنیم. یک انتزاع به جای یک پیاده سازی. ما می توانیم این را در شرایط واقعی به این صورت ترجمه کنیم که " من می دانم که ابزار احتیاج به یک پیوست دارند. اهمیت نمی دهیم که این یک دریل است یا یک اره" کد ما می تواند به صورت زیر باشد:

    public interface IAttachment  
    {  
        void DoTask();  
    }  
      
    public class DrillBit : IAttachment  
    {  
        void DoTask()  
        {  
            // drill stuff  
        }  
    }  
      
    public class SawBlade : IAttachment  
    {  
        void DoTask()  
        {  
            // saw stuff  
        }  
    }  
      
    public class CordlessTool  
    {  
        private IAttachment _attachment;  
      
        public CordlessTool(IAttachment attachment)  
        {  
            _attachment = attachment;  
        }  
      
        public void GivePowerToAttachment()  
        {  
            _attachment.DoTask();  
        }  
    }  

این مثال مزایای آنچه که انجام دادیم را نشان می دهد. ما یک کلاس در نظر گرفتیم که حالا مسئول آن است که به ضمیمه ها قدرت بدهد و فقط همین کار را انجام می دهد. به این صورت راحتتر نگهداری می شود و کمتر دست و پا گیر است. این به راحتی قابل ارتقا است، و می تواند unit tested(واحد تست) باشد بدون توجه به آنچه که در واقع چه IAttachment ای  بخش  DoTask() را انجام می دهند(یعنی مهم نیست کدام بخش، کار مورد نظر را انجام می دهد).

آموزش سی شارپ

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • C#.net
  • 2k بازدید
  • 3 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید