شما می توانید با عضویت در انجمن پرسش و پاسخ درسمن هرگونه سوالی دارید را مطرح کنید

بهترین درک از تزریق وابستگی در جاوا

تاریخ بروزرسانی : پنجشنبه 18 مهر 1398

تعداد بازدید : 431

گروه دوره : Java

زمان خواندن مقاله : 15 دقیقه

اگر میخواهید وابستگی را از سطح کلاس خود کاهش دهید و از تزریق وابستگی استفاده کنید و سردرگم شده اید این مطلب را مطالعه کنید.

بهترین درک از تزریق وابستگی در جاوا

آموزش مفاهیم تزریق وابستگی در جاوا

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

اولین کاری که انجام میدهید این است که گوشی خود را به یک نمایندگی برده تا صفحه نمایش آن را  تغییر دهد. حالا فرض کنید که گوشی شما جوری طراحی شده است که با آسیب دیدن صفحه نمایش نیاز باشد تا یک گوشی جدید تهیه کنید!!!!
یا برای کارخود لپ تاپ تهیه کردید. بعد از مدتی نیاز دارید تا حافظه رم لپ تاپ رو افزایش دهید، در این حالت شما لپ تاپ را پیش نمایندگی یا یک کارشناس در این زمینه می برید تا حافظه رم لپ تاپ شما را افزایش دهد. حال فرض کنید که لپ تاپ شما همچنین قابلیتی نداشته باشد و شما نیاز داشته باشید که  برای تغییر یا ارتقا حافظه ، یک لپ تاپ جدید خریداری کنید!
 برای حل این مشکل، لوازم الکتریکی از قطعات مختلفی تشکیل شدند که قابلیت تغییر یا تعویض رادارند. به این قابلیت طراحی ماژولار گفته میشود.
 در پیاده سازی سیستم های نرم افزاری، شما باید به عنوان یک برنامه نویس  با چنین دیدی نسبت به پیاده سازی نرم افزار اقدام کنید یعنی کاری کنید که وابستگی ها را از سطح کلاس کاهش داده و در زمان نیاز این وابستگی را خودمان ایجاد کنیم برای بیان این مساله در برنامه نویسی از واژه  Dependency Injection یا تزریق وابستگی استفاده میکنند.
ما قصد داریم تا شما را با مفهوم تزریق وابستگی در جاوا آشنا کنیم.

dependency injection در جاوا چیست؟

dependency injection  یک الگوی طراحی است که هدفش حذف وابستگی های بین دو کلاس با استفاده از کد است به مثال زیر در جاوا توجه کنید، وقتی Class1 به Class2 وابستگی دارد ما این وابستگی را با تعریف یک فیلد از Class2 در Class1 تعریف می کنیم و سپس با استفاده از کلمه کلیدی new یک شئ از Class2 می سازیم:
public class Class1 {
    public Class2 class2 = new Class2();
}

بیان دقیق تر تزریق وابستگی یا Dependency injection چیست؟

در واقع تزریق وابستگی یک تکنیک در برنامه نویسی است که باعث می شود کلاس های شما مستقل از وابسته هایشان عمل کنند. این امر با استفاده جدا کردن «استفاده از یک شی» از «ساخت آن شی» حاصل می شود. این تکنیک به برنامه نویسان کمک می کند که بتوانند دو اصل از اصول طراحی شی گرا یعنی  Dependency inversion principle  یا اصل وابستگی معکوس و Single responsibility principle  یا اصل تک مسئولیتی  را بتوانند رعایت کنند.
Dependency injection  یا تزریق وابستگی معکوس باعث می شود که کلاس های ما کمترین وابستگی را به هم داشته باشند و اصطلاحاً به یک معماری  Loosely coupled(اتصال آزادانه) برسیم.
در تزریق وابستگی ۴ نقش اصلی وجود دارد:
  1. شی service که مورد استفاده قرار می گیرد.
  2. شی client که از سرویس استفاده می کند.
  3. اینترفیس ها که نحوه استفاده client از service را مشخص می کند.
  4. Injector، وظیفه آن ساخت شی سرویس تا آن را در اختیار Client قرار دهد.
اکنون به بیان تعریف نقش های گفته شده در تزریق وابستگی جاوا میپردازیم:
شی service: هر شیئی که قرار است سرویسی ارائه دهد به عنوان شی service شناخته می شود.
شی client: هر شیئی که از شی service استفاده می کند به عنوان شی client شناخته می شود.
Interface: اینترفیس چیزی است که client انتظار دارد service ها در اختیارش بگذارند. اینترفیس توسط سرویس پیاده سازی می شود و فرآیند injection توسط اینترفیس ها انجام می شود. اینترفیس ها کلاس های concrete نیستند یعنی در داخل خود اینترفیس، چیزی پیاده سازی نمی شود بلکه اینترفیس ها در سطح انتزاع یا Abstract می باشند.
منظور از انتزاع دید کلی نسبت به یک شیء است مثلا وقتی می‌گوییم میز، چیزی که در ذهن ما نقش می‌بندد یک شکل کلی است ولی وقتی می‌گوییم میز ناهارخوری دقیقا مشخص می‌کنیم که چه نوع میزی است. در نتیجه انتزاع یک دید کلی از یک شیء بحساب می‌آید
در واقع Client  نباید نسبت به نحوه پیاده سازی سرویس هایی که از آن استفاده می کند هیچ اطلاعاتی داشته باشد. اینترفیس ها رابط کلاس سرویس و کلاینت هستند.
 Injector:  Injector وظیفه معرفی سرویس ها به کلاینت را بر عهده داردInjector ها عموماً به صورت پکیج های خارجی در زبان های مختلف برنامه نویسی وجود دارند و لازم نیست برنامه نویس خودش یک injector توسعه دهد.
 

دلیل استفاده از تزریق وابستگی:

قبل از دلیل استفاده از تزریق وابستگی باید بدانید که یک نوع تزریق وابستگی به نام  Dependency injection  hard یا وابستگی سخت وجود دارد که باعث بروز مشکلاتی در برنامه  میشود هر چه برنامه گسترش پیدا کند این مشکلات نیز بیشتر میشود و هدف  استفاده از تزریق وابستگی کاهش این مشکلات است.
مشکلاتی که وابستگی سخت یا hard Dependency injection به وجود می آورد عبارت است از:
کاهش قابلیت گسترش برنامه
کاهش قابلیت نگهداری
کاهش قابلیت استفاده مجدد
کاهش قابلیت تست
پس ایده اصلی Dependency Injection این می باشد که اتصالات و وابستگی را بصورت جدا از هم ایجاد کرد، بصورتی که کلاس مادر یا شی ایجاد شده به راحتی قابل آزمایش و اجرا باشد.
اصولا مشکل زمانی پیش خواهد آمد که ما یک کلاس را ایجاد کرده باشیم و در آینده بخواهیم در یک شی تغییراتی ایجاد کنیم  این تغییرات بسیار دشوار می باشد چون به دلیل استفاده نکردن از تزریق وابستگی باید تمام نمونه های آن شی را تغییر دهیم.

روش ها استفاده از تزریق وابستگی در جاوا:

  1. سازنده (Constructor Injection): در این روش شی‌ای از کلاس سطح پایین به سازنده کلاس سطح بالا ارسال می‌شود که در نهایت نوع آن از جنس Interface است.
  2. متد (Method Injection): همان طور که درسازنده گفتیم کلاس سطح بالا حتما و حتما از یک کلاس سطح پایین برای اجرای فرآیند پیش‌فرض خود استفاده میکند. حال اگر بخواهیم تنها یک متد مشخص از یک کلاس را درگیر بحث تزریق وابستگی کنیم باید آن وابستگی را به یک آرگومان، یک متد مشخص ارسال کنیم. بنابراین تزریق متد تنها و تنها روی یک متد مشخص صورت میگیرد و طی آن وابستگی‌های کلاس‌های سطح پایین به متدی از کلاس سطح بالا ارسال می‌شود.


مثال از تزریق وابستگی در جاوا:

اکنون که با تزریق وابستگی در جاوا آشنا شدید میخواهیم این روش را در قالب یک مثال کاربردی برای درک بهتر موضوع برای شما عزیزان بیان کنیم.
فرض کنید شما قصد دارید در سیستم خود یک بخش برای ارسال ایمیل پس از ثبت نظر کاربر ایجاد نمایید. شما کلاسی ایجاد خواهید کرد که با استفاده از کلاس پیش فرض ایمیل این کار را برای شما انجام دهد. حالا مدتی بعد مدیرپروژه به  شما می گوید که می خواهد به سیستم نظرات خود قابلیت ارسال پیامک را اضافه کند. خوب حالا شما چه کار میکنید؟ 
یک کلاس دیگر مجددا برای ارسال پیامک ایجاد خواهید کرد که از کلاس پیش فرض  ارسال پیامک شما استفاده کند.
در واقع ما با هر بار درخواست، دائماً در حال تغییر کدهای نوشته شده داخل کلاس هستیم.
پس چه کاری انجام دهیم که مجبور به تغییر زمان بر کدها نباشیم؟
بله استفاده از تزریق وابستگی در جاوا.
همانطور که می دانیم هم ایمیل و هم پیامک یک گیرنده و یک متن دارند البته ممکن است در برخی موارد مانند سرویس دهنده متفاوت باشند اما نتیجه نهایی هر دو ارسال پیام به کاربر است.
 پس در اینجا می توانیم با استفاده از تزریق وابستگی در جاوا و یک رابط کاربری یا همان Interface کلاس مادر خود را طوری ایجاد کنیم که به راحتی از آن استفاده کنیم و بتوانیم  اگر روزی نیاز به استفاده از روش های دیگری همچون ارسال پیام صوتی و تصویری و.. بود  از همین کلاس استفاده نماییم.
حالا میخواهیم نمونه کدی را با استفاده  از تزریق وابستگی در جاوا، مورد بررسی قرار دهیم:
کلاسی داریم بنام MessageService که کار ارسال پیام را به چند صورت می خواهد انجام دهد.  ما دو کلاس برای ارسال پیام ایجاد کرده ایم که دو نوع پیام را ارسال میکند
بدون استفاده از DI  که مخفف Dependency Injection است کدهای ما بصورت زیر خواهد بود:
class TypeA{
 sendMessage(){
    ---------
    ---------
 }
}
 
class TypeB{
 sendMessage(){
  ---------
  ---------
 }
}
class SendMessageApplication{
   main(){
     send(type);
  }

  send(int type){
     if(type == 1){
        TypeA a = new TypeA();
        a.sendMessage();
     }else{
        TypeB b = new TypeB();
        b.sendMessage();
     }
  }
}

در آینده اگر بخواهیم در کلاس نوع A تغییری ایجاد کنیم برای نمونه نوع C نیز این کار را باید بصورت دستی انجام دهیم، حالا اگر پروژه بسیار بزرگ باشد تصور کنید این کار چقدر دشوار تر خواهد شد.
 

و اما راه حل مساله:
 
ما یک رابط کاربری (interface) ایجاد میکنیم که کار ارسال پیام را انجام دهد و دارای یک متد بنام  sendMessage  باشد.
حال تمامی سرویس دهنده های ما (همان کلاس های ارسال پیام) باید این رابط کاربری  را implement  کنند.
با این کار ما کلاس هایی داریم که همگی از یک رابط کاربری استفاده کرده اند و متدی بنام sendMessage را درون خود دارند که عملیات نهایی ارسال پیام را با توجه به نوع آن برای نمونه کلاس اول متن را بصورت انگلیسی و کلاس دوم بصورت فارسی می فرستد.
حال  ما در تابع setter  در کلاس MessageApplication از طریق تزریق وابستگی، نوع سرویس مورد نظر( همان کلاس های ارسال پیام) را گرفته و با استفاده از متد messageService.sendMessage();  که اشاره به تابع sendMessage() رابطِ کاربری ما دارد برنامه را اجرا و عملیات ارسال پیام را انجام میدهیم.
پس با استفاده از تزریق وابستگی ها کلاس های ما بصورت زیر تغییر خواهند کرد:

interface MessageService{

  sendMessage();

}

 

class TypeA implements MessageService{

 void sendMessage(){

   //------------

   //------------

 }

}

 

class TypeB implements MessageService{

 void sendMessage(){

   //-----------

   //-----------

 }

}

//----------------------------------------------------

class MessageApplication{

  MessageService messageService;

  void setMessageService(MessageService service){

    this.messageService = service;

  }

  void sendMessage(){

   messageService.sendMessage();

 }

}
حال شما می تواند با ایجاد یک شی از کلاس MessageApplication و فراخوانی sendMessage()  به راحتی از دو روش ارسال پیام یعنی کلاس های A  و B استفاده کنید و حتی انواع دیگری نیز ایجاد نمایید و بدون تغییر در کلاس MessageApplication  تنها از نوع جدید استفاده کنید.
مزایای dependency injection:
  • در dependency injection نیازی به compile مجدد کد ها وجود ندارد و در زمان اجرا compile می شوند.
  • کد های مورد استفاده در یک کلاس کاهش می یابد.
  • توسعه کدها به صورت آنلاین و استفاده از آنها در برنامه.
معایب تزریق وابستگی در جاوا:
  • خواندن کد را به شدت سخت می کند چون تمامی کدها در یک بخش قرار ندارند هر کدام در کلاس های جداگانه قرار دارند.
  • نیازمند تجربه جهت پیاده سازی، زیرا اگر توانایی بالا در نوشتن کد نداشته باشید به یک عیب در برنامه تبدیل خواهد شد.
  • پیچیده بودن مدیریت تزریق وابستگی.
 


اشتراک گذاری


توضیحاتی در مورد نویسنده این مقاله :
مرضیه فتاحی مرضیه فتاحی

کارشناس کامپیوتر گرایش نرم افزار..... نویسندگی،تجربه ای انفرادی است یعنی به اشتراک گذاری.... این بخشی از ذات انسان است که بخواهد مسائل را به اشتراک بگذارد ازجمله:افکار،ایده ها،عقاید


نظر بدهید

نشانی ایمیل شما منتشر نخواهد شد .
برای ارسال نظر نیاز است وارد سایت شوید. در صورت نداشتن حساب کاربری عضو شوید.

گروه مقالات


آموزشی
21
علمی
21
تحقیقاتی
29


به دنبال هر آموزشی هستید در اینجا به دنبال آن باشید .