নির্ভরতা ইনজেকশন কী?


3074

নির্ভরতা ইনজেকশন সম্পর্কে সুনির্দিষ্ট প্রশ্ন সহ ইতিমধ্যে পোস্ট করা বেশ কয়েকটি প্রশ্ন রয়েছে , যেমন এটি কখন ব্যবহার করবেন এবং এর জন্য কী ফ্রেমওয়ার্ক রয়েছে। যাহোক,

নির্ভরতা ইনজেকশন কী এবং কখন / কেন এটি ব্যবহার করা উচিত নয়?


নির্ভরতা ইনজেকশন সম্পর্কে আমার আলোচনা এখানে দেখুন
কেভিন এস।

33
আমি লিঙ্ক সম্পর্কিত মন্তব্য সাথে একমত। আমি বুঝতে পারি আপনি অন্য কারও রেফারেন্স দিতে চাইতে পারেন। তবে অন্তত যুক্ত করুন যে আপনি কেন তাদের লিঙ্ক করছেন এবং এই লিঙ্কটি অন্যান্য লিঙ্কগুলির চেয়ে আরও ভাল করে তোলে যা আমি গুগল ব্যবহার করে পেতে পারি
ক্রিশ্চিয়ান পায়েেন

@আর: প্রযুক্তিগতভাবে, নির্ভরতা ইনজেকশন আইওসির কোনও বিশেষ রূপ নয় । বরং, আইওসি একটি কৌশল যা নির্ভরতা ইনজেকশন সরবরাহ করতে ব্যবহৃত হয়। ডিপেন্ডেন্সি ইনজেকশন সরবরাহ করতে অন্যান্য কৌশল ব্যবহার করা যেতে পারে (যদিও আইওসি সাধারণ ব্যবহারে একমাত্র), এবং অন্যান্য সমস্যাগুলির জন্যও আইওসি ব্যবহৃত হয়।
শান রিলি

আমি ডিআই সম্পর্কে যে সর্বোত্তম ব্যাখ্যাটি পড়েছি তার মধ্যে একটি হ'ল গুগলের গুইস (রস হিসাবে উচ্চারণ করা) http://code.google.com/p/google-guice/wiki/Motivation?tm=6
রাজ

136
লিঙ্কগুলি সম্পর্কে, মনে রাখবেন যে তারা প্রায়শই একটি উপায় বা অন্যভাবে অদৃশ্য হয়ে যায়। এসও উত্তরে মৃত লিঙ্কগুলির ক্রমবর্ধমান সংখ্যা রয়েছে। সুতরাং, লিঙ্কযুক্ত নিবন্ধটি যতই ভাল হোক না কেন, এটি খুঁজে না পেলে এটি মোটেও ভাল।
ডক করুন

উত্তর:


1931

নির্ভরতা ইনজেকশন অন্যান্য বস্তু বা কাঠামোর (নির্ভরতা ইনজেক্টর) এর উপর নির্ভরতা কেটে যাচ্ছে।

নির্ভরতা ইনজেকশন পরীক্ষা সহজ করে তোলে। ইনজেকশনটি কনস্ট্রাক্টরের মাধ্যমে করা যেতে পারে ।

SomeClass() নিম্নলিখিত হিসাবে এর নির্মাতা আছে:

public SomeClass() {
    myObject = Factory.getObject();
}

সমস্যা : যদি myObjectডিস্ক অ্যাক্সেস বা নেটওয়ার্ক অ্যাক্সেসের মতো জটিল কাজগুলি জড়িত থাকে তবে ইউনিট পরীক্ষা চালানো শক্তSomeClass() । প্রোগ্রামারদের বিদ্রূপ করতে হবে myObjectএবং কারখানার কলটি আটকাতে পারে ।

বিকল্প সমাধান :

  • পাসিং myObjectকন্সট্রাকটর একটি যুক্তি হিসেবে
public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

myObject সরাসরি পাস করা যেতে পারে যা পরীক্ষা সহজ করে তোলে।

  • একটি সাধারণ বিকল্প হ'ল ডু -কিছুই কনস্ট্রাক্টর সংজ্ঞায়িত করা । নির্ভরতা ইনজেকশন সেটারের মাধ্যমে করা যেতে পারে। (এইচ / টি @ মাইকভেলা)।
  • মার্টিন ফোলার একটি তৃতীয় বিকল্প (এইচ / টি @ মার্কডিক্স) নথি করে, যেখানে ক্লাসগুলি স্পষ্টভাবে নির্ভরতা প্রোগ্রামারদের জন্য একটি ইন্টারফেস প্রয়োগ করে যা ইনজেকশনের ইচ্ছা করে।

নির্ভরতা ইনজেকশন ছাড়াই ইউনিট টেস্টিংয়ের উপাদানগুলি আলাদা করা শক্ত।

২০১৩-এ, যখন আমি এই উত্তরটি লিখেছিলাম, এটি গুগল টেস্টিং ব্লগে একটি প্রধান থিম ছিল । এটি আমার পক্ষে সবচেয়ে বড় সুবিধা হিসাবে রয়ে গেছে, কারণ প্রোগ্রামারদের সর্বদা তাদের রান-টাইম ডিজাইনে অতিরিক্ত নমনীয়তার প্রয়োজন হয় না (উদাহরণস্বরূপ, পরিষেবা লোকেটার বা অনুরূপ নিদর্শনগুলির জন্য)। প্রোগ্রামারদের প্রায়শই পরীক্ষার সময় ক্লাস বিচ্ছিন্ন করা প্রয়োজন।


25
বেন হফস্টিনের রেফারেন্টো মার্টিন ফাউলারের নিবন্ধটি বিষয়টির উপর 'আবশ্যক-পঠন' ইঙ্গিত হিসাবে প্রয়োজনীয় বলে স্বীকার করে, আমি wds এর উত্তর গ্রহণ করছি কারণ এটি এখানে এসও-তে প্রশ্নের উত্তর দেয়।
এআর।

121
ব্যাখ্যা এবং অনুপ্রেরণার জন্য +1: এমন শ্রেণীর অবজেক্টগুলির তৈরি করা যার উপর একটি শ্রেণি অন্য কারও সমস্যা নির্ভর করে । এটি বলার আরেকটি উপায় হ'ল ডিআই ক্লাসগুলিকে আরও সংহত করে তোলে (তাদের কম দায়িত্ব আছে)।
ফুহরম্যানেটর

13
আপনি বলছেন যে নির্ভরতা "কনস্ট্রাক্টরের কাছে" কেটে গেছে তবে আমি এটি যেভাবে বুঝতে পেরেছি এটি কঠোরভাবে সত্য নয়। এটি এখনও নির্ভরতা ইনজেকশন যদি অবজেক্টটি তাত্ক্ষণিকভাবে চালুর পরে কোনও সম্পত্তি হিসাবে নির্ভরতা সেট করা হয়, তাই না?
মাইক ভেলা

1
@ মাইকভেলা হ্যাঁ, এটি সঠিক। এটি বেশিরভাগ ক্ষেত্রেই প্রকৃত কোনও পার্থক্য করে না, যদিও বৈশিষ্ট্যগুলি সাধারণত কিছুটা নমনীয়। আমি এটি উল্লেখ করতে পাঠ্যটি সামান্য সম্পাদনা করব।
wids

2
আমি এখনও অবধি খুঁজে পাওয়া সেরা উত্তরগুলির মধ্যে একটি, এইভাবে আমি এটির উন্নতি করতে আগ্রহী। এটি নির্ভরতা ইনজেকশনের তৃতীয় রূপের বর্ণনা অনুপস্থিত: ইন্টারফেস ইনজেকশন
মার্ক ডিক্স 21

2351

আমি এখন পর্যন্ত যে সেরা সংজ্ঞাটি পেয়েছি তা হ'ল জেমস শোরের একটি :

"নির্ভরতা ইনজেকশন" একটি 5-শতাংশ ধারণার জন্য 25 ডলার শব্দ is [...] নির্ভরতা ইনজেকশন মানে কোনও বস্তুকে তার উদাহরণ ভেরিয়েবল দেওয়া। [...]।

মার্টিন ফাউলারের একটি নিবন্ধ রয়েছে যা কার্যকরও প্রমাণ হতে পারে।

নির্ভরতা ইনজেকশনটি মূলত কোনও বস্তুর নিজস্ব নির্মাণের পরিবর্তে প্রয়োজনীয় বস্তুগুলি সরবরাহ করে (তার নির্ভরতা)। এটি পরীক্ষার জন্য একটি খুব দরকারী কৌশল, যেহেতু এটি নির্ভরশীলতাগুলিকে ঠাট্টা করা বা স্টাব করার অনুমতি দেয়।

নির্ভরতাগুলি বিভিন্ন উপায়ে ইনজেক্ট করা যায় (যেমন কনস্ট্রাক্টর ইনজেকশন বা সেটার ইনজেকশন)। কেউ এটি করতে বিশেষায়িত নির্ভরতা ইনজেকশন ফ্রেমওয়ার্কগুলি (উদাহরণস্বরূপ স্প্রিং) ব্যবহার করতে পারেন তবে তাদের অবশ্যই প্রয়োজন হয় না। নির্ভরতা ইনজেকশন লাগানোর জন্য আপনার সেই ফ্রেমওয়ার্কগুলির দরকার নেই। অবজেক্টগুলি (নির্ভরতা) সুস্পষ্টভাবে ইনস্ট্যান্ট করা এবং পাস করা ফ্রেমওয়ার্ক অনুসারে ইনজেকশন হিসাবে ঠিক তেমনই ভাল ইনজেকশন।


35
আমি জেমসের নিবন্ধের ব্যাখ্যাটি বিশেষত শেষের মতো দেখতে চাই: "তবুও, আপনাকে যে কোনও পদ্ধতির অবাক করে তিনটি ধারণা ('ট্রিপপ্ল্যানার,' 'ক্যাব এজেন্সি,' এবং 'এয়ারলাইন এজেন্সি') লাগে সেগুলি আপনাকে নয়টি প্লাস শ্রেণিতে পরিণত করে, এবং তারপরে অ্যাপ্লিকেশন লজিকের একক লাইন রচনার আগে কয়েক ডজন লাইন আঠালো কোড এবং কনফিগারেশন এক্সএমএল যুক্ত করে। " এটি আমি প্রায়শই দেখেছি (দুঃখের সাথে) - যে নির্ভরতা ইনজেকশন (যা তাঁর ব্যাখ্যা অনুযায়ী ভাল) সেগুলি সহজে করা যেতে পারে এমন জিনিসগুলিকে অতিরিক্তভাবে জটিল করার জন্য অপব্যবহার করা হয় - "সমর্থনকারী" কোড লেখা শেষ করে ...
ম্যাট

2
পুনরায়: "অবজেক্টগুলি (নির্ভরতা) সুস্পষ্টভাবে ইনস্ট্যান্ট করা এবং পাস করা ফ্রেমওয়ার্কের মাধ্যমে ইনজেকশন হিসাবে ঠিক তেমনই ভাল ইনজেকশন"। তাহলে লোকেরা ফ্রেমওয়ার্ক তৈরি করল কেন?
dzieciou

13
একই কারণের জন্য প্রতিটি কাঠামোটি (বা কমপক্ষে পাওয়া উচিত) লিখিত হয়: কারণ এখানে প্রচুর পুনরাবৃত্তি / বয়লারপ্লিট কোড রয়েছে যা একবার নির্দিষ্ট জটিলতায় পৌঁছানোর পরে রচনা করা দরকার। সমস্যাটি অনেক সময় হয় যখন লোকেরা কোনও কাঠামোর জন্য পৌঁছায় এমনকি এটির কঠোরভাবে প্রয়োজন হয় না।
থিয়াগো অ্যারেজ

14
-5-শতাংশ ধারণার জন্য 25 মেয়াদ শেষ। এখানে একটি ভাল নিবন্ধ যা আমাকে সাহায্য করেছে: codeproject.com/Articles/615139/…
খ্রিস্টিন

@ ম্যাট কনফিগারেশন ফাইলগুলি কেবল "সিদ্ধান্ত স্থগিত করা" এর চূড়ান্ত দিকে নিয়ে যায় - "সিদ্ধান্তটি বাস্তব রানটাইম পর্যন্ত স্থগিত করুন"। ডাগার এবং বিশেষত ড্যাগার আমার মতে মিষ্টি স্পটটি খুঁজে পেয়েছেন "আবেদন স্থগিতের সময় পর্যন্ত সিদ্ধান্ত স্থগিত করুন"।
থোরবজর্ন রাভন অ্যান্ডারসন

645

আমি এই মজার উদাহরণটি শিথিল মিলনের ক্ষেত্রে পেয়েছি :

যে কোনও অ্যাপ্লিকেশন এমন অনেকগুলি অবজেক্টের সমন্বয়ে গঠিত যা কিছু দরকারী জিনিস সম্পাদনের জন্য একে অপরের সাথে সহযোগিতা করে। Ditionতিহ্যগতভাবে প্রতিটি বস্তু যার সাথে সহযোগিতা করে তার উপর নির্ভরশীল অবজেক্টগুলির (নির্ভরতা) এর নিজস্ব রেফারেন্স পাওয়ার জন্য দায়বদ্ধ। এটি উচ্চ মিলিত ক্লাস এবং হার্ড-টু-টেস্ট কোডের দিকে নিয়ে যায়।

উদাহরণস্বরূপ, একটি Carবিষয় বিবেচনা করুন ।

একটি Carচালনার জন্য চাকা, ইঞ্জিন, জ্বালানী, ব্যাটারি ইত্যাদির উপর নির্ভর করে। Ditionতিহ্যগতভাবে আমরা বস্তুর সংজ্ঞা সহ এই জাতীয় নির্ভর বস্তুর ব্র্যান্ডকে সংজ্ঞায়িত করি Car

নির্ভরতা ইনজেকশন (ডিআই) ছাড়াই:

class Car{
  private Wheel wh = new NepaliRubberWheel();
  private Battery bt = new ExcideBattery();

  //The rest
}

এখানে, Carঅবজেক্ট নির্ভর বস্তু তৈরির জন্য দায়বদ্ধ।

যদি আমরা তার নির্ভরশীল অবজেক্টের ধরণটি পরিবর্তন করতে চাই - তবে বলুন Wheel- প্রাথমিক NepaliRubberWheel()পাঙ্কচারের পরে ? আমাদের নতুন নির্ভরতার সাথে কার অবজেক্টটি ChineseRubberWheel()আবার Carতৈরি করতে হবে , তবে কেবল নির্মাতারা এটি করতে পারবেন।

তাহলে আমাদের কী Dependency Injectionকরবে ...?

নির্ভরতা ইনজেকশন ব্যবহার করার সময়, সামগ্রীগুলি সংকলনের সময় (গাড়ী উত্পাদন সময়) না বলে রান সময়ে তাদের নির্ভরতা দেওয়া হয় । যাতে আমরা এখন Wheelযখনই চাই পরিবর্তন করতে পারি। এখানে, dependency( wheel)) Carরান টাইমে ইনজেকশন দেওয়া যেতে পারে ।

নির্ভরতা ইনজেকশন ব্যবহার করার পরে:

এখানে, আমরা ইনজেকশনের নির্ভরতা রানটাইম দিকে (চাকা এবং ব্যাটারি)। তাই শব্দটি: নির্ভরতা ইনজেকশন।

class Car{
  private Wheel wh; // Inject an Instance of Wheel (dependency of car) at runtime
  private Battery bt; // Inject an Instance of Battery (dependency of car) at runtime
  Car(Wheel wh,Battery bt) {
      this.wh = wh;
      this.bt = bt;
  }
  //Or we can have setters
  void setWheel(Wheel wh) {
      this.wh = wh;
  }
}

উত্স: নির্ভরতা ইনজেকশন বোঝা


20
আমি এটি যেভাবে বুঝতে পারি তা হ'ল অন্য বস্তুর অংশ হিসাবে কোনও নতুন অবজেক্টটি তাত্ক্ষণিক না করে আমরা কখনই এবং যদি প্রয়োজন হয় তবে এটির উপর প্রথম অবজেক্টের নির্ভরতা অপসারণ করার প্রয়োজন আছে said এটা কি সঠিক?
জেলিবিয়ানমচাইন

আমি এখানে একটি কফি শপের উদাহরণ সহ এটি বর্ণনা করেছি: digigene.com/design-patterns/d dependency
Ali

11
সত্যিই এই উপমাটি পছন্দ করুন কারণ এটি সাধারণ উপমা ব্যবহার করে সাধারণ ইংরেজী English আমি টয়োটা নই, ইতিমধ্যে বন্ধ ঘূর্ণায়মান নকশা থেকে একটা গাড়ী তৈরীর অত্যধিক আর্থিকভাবে অতিবাহিত এবং মানুষ শক্তি, লাইন জড় যদি বলি সেখানে বিদ্যমান নামকরা টায়রা প্রযোজক হয়, আমি কেন টায়রা উৎপাদন বিভাগের অর্থাত করতে গোড়া থেকে শুরু করা উচিত newএকটি পাগড়ি? আমি না। আমাকে যা করতে হবে তা হল তাদের কাছ থেকে (পরমের মাধ্যমে ইনজেকশন) কেনা, ইনস্টল এবং ওয়াহ-লাহ! সুতরাং, প্রোগ্রামিংয়ে ফিরে এসে বলুন একটি সি # প্রকল্পের একটি বিদ্যমান লাইব্রেরি / শ্রেণি ব্যবহার করা দরকার, চালানোর / ডিবাগ করার দুটি উপায় আছে, এর সম্পূর্ণ প্রকল্পের 1-উল্লেখ উল্লেখ করুন
Jeb50

(না), .. বাহ্যিক গ্রন্থাগার / শ্রেণি বা ডিএলএল থেকে এটি 2-যোগ করুন। আমাদের এই বাহ্যিক শ্রেণীর ভিতরে কী রয়েছে তা যদি না দেখতে পারা যায় তবে এটিকে ডিএলএল হিসাবে যুক্ত করা সহজ উপায়। সুতরাং বিকল্প 1 newএটির জন্য, বিকল্প 2 এটি পরম হিসাবে প্রেরণ করবে। সঠিক হতে পারে না, তবে সহজ বোকা বুঝতে সহজ।
Jeb50

1
@ জেলিবিয়ানম্যাচিন (একটি মন্তব্যে চূড়ান্ত দেরী জবাবের জন্য দুঃখিত ..) এটি নয় যে আমরা হুইল অবজেক্ট বা ব্যাটারি অবজেক্টের উপর প্রথম অবজেক্টের নির্ভরতা অপসারণ করি, এটি আমরা নির্ভরতা পাস করি, যাতে আমরা উদাহরণ বা বাস্তবায়ন পরিবর্তন করতে পারি নির্ভরতা। পূর্বে: নেপালি রবারওহিলের উপরে গাড়ীর একটি হার্ডকোডযুক্ত নির্ভরতা রয়েছে। পরে: গাড়ির চাকার উদাহরণে একটি ইঞ্জেকড নির্ভরতা রয়েছে।
মিকেল ওহলসন

263

ডিপেন্ডেন্সি ইনজেকশন এমন একটি অনুশীলন যেখানে অবজেক্টগুলি এমনভাবে ডিজাইন করা হয়েছে যেখানে তারা অভ্যন্তরীণভাবে বিন্যাসের পরিবর্তে কোডের অন্যান্য টুকরা থেকে বস্তুর উদাহরণ গ্রহণ করে। এর অর্থ হল যে কোনও বস্তু ইন্টারফেস প্রয়োগ করে যা বস্তুর দ্বারা প্রয়োজনীয় তা কোড পরিবর্তন না করেই প্রতিস্থাপিত হতে পারে যা পরীক্ষার সহজতর করে এবং ডিকপলিংয়ের উন্নতি করে।

উদাহরণস্বরূপ, এই ক্লাসগুলি বিবেচনা করুন:

public class PersonService {
  public void addManager( Person employee, Person newManager ) { ... }
  public void removeManager( Person employee, Person oldManager ) { ... }
  public Group getGroupByManager( Person manager ) { ... }
}

public class GroupMembershipService() {
  public void addPersonToGroup( Person person, Group group ) { ... }
  public void removePersonFromGroup( Person person, Group group ) { ... }
} 

এই উদাহরণস্বরূপ, এর কাজটি করার জন্য বাস্তবায়নের প্রয়োজন হবে PersonService::addManagerএবং এর PersonService::removeManagerএকটি উদাহরণ প্রয়োজন GroupMembershipService। নির্ভরতা ইনজেকশন ছাড়াই, এটি করার theতিহ্যগত উপায়টি হ'ল GroupMembershipServiceকনস্ট্রাক্টারে কোনও নতুনকে PersonServiceইনস্ট্যান্টিয়েট করা এবং উভয় ফাংশনে সেই দৃষ্টান্ত বৈশিষ্ট্যটি ব্যবহার করা। যাইহোক, যদি নির্মাণকারীর GroupMembershipServiceএকাধিক জিনিস প্রয়োজন হয় তবে এটি আরও খারাপ হতে পারে, কিছু সূচনা "সেটটার" রয়েছে যেগুলিকে ডেকে আনা দরকার GroupMembershipService, কোডটি বরং দ্রুত বৃদ্ধি পায়, এবং PersonServiceএখন কেবলমাত্র নয়, GroupMembershipServiceতবে সমস্ত কিছুর উপরও নির্ভর করে যে GroupMembershipServiceনির্ভর করে. তদ্ব্যতীত, সংযোগটি GroupMembershipServiceহার্ডকোডযুক্ত PersonServiceযার অর্থ আপনি "ডামি আপ" করতে পারবেন না এ aGroupMembershipService পরীক্ষার উদ্দেশ্যে, বা আপনার প্রয়োগের বিভিন্ন অংশে কৌশল প্যাটার্ন ব্যবহার করতে use

ডিপেন্ডেন্সি ইনজেকশন সহ, GroupMembershipServiceআপনার অভ্যন্তরটি তাত্ক্ষণিকভাবে পরিবর্তিত করার পরিবর্তে PersonServiceআপনি এটি PersonServiceনির্মাণকারীর কাছে প্রবেশ করিয়ে দিন অথবা অন্য কোনও স্থানীয় উদাহরণ সেট করার জন্য কোনও সম্পত্তি (গেটর এবং সেটার) যুক্ত করুন। এর অর্থ হ'ল আপনার PersonServiceকীভাবে কীভাবে তৈরি করা যায় তা নিয়ে চিন্তা করার দরকার নেই GroupMembershipService, এটি কেবল যা দিয়েছেন তা গ্রহণ করে এবং তাদের সাথে কাজ করে। এর অর্থ এটিও হ'ল যে কোনও কিছু যা একটি সাবক্লাস GroupMembershipService, বা GroupMembershipServiceইন্টারফেস প্রয়োগ করে তাকে "ইনজেকশন" দেওয়া যেতে পারে PersonServiceএবং PersonServiceপরিবর্তনের বিষয়ে জানার দরকার নেই।


29
আপনি ডিআই ব্যবহারের পরে একই কোড উদাহরণটি দিতে পারলে দুর্দান্ত হত
কোডিবাগস্টিন

170

গৃহীত উত্তরটি একটি ভাল - তবে আমি এটিতে যুক্ত করতে চাই যে ডিআই অনেকটা কোডের হার্ডকোডযুক্ত ধ্রুবকগুলিকে এড়িয়ে চলা ক্লাসিকের মতো।

আপনি যখন কোনও ডাটাবেস নামের মতো ধ্রুবক ব্যবহার করেন আপনি তাড়াতাড়ি কোডের অভ্যন্তর থেকে কিছু কনফিগার ফাইলে সরিয়ে নিয়ে যান এবং সেই মানটি যেখানে প্রয়োজন সেখানে স্থান পরিবর্তন করে। এটি করার কারণ হ'ল এই ধ্রুবকগুলি সাধারণত বাকি কোডের চেয়ে বেশি ঘন ঘন পরিবর্তন হয়। উদাহরণস্বরূপ, যদি আপনি একটি পরীক্ষা ডাটাবেসে কোড পরীক্ষা করতে চান।

অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিংয়ের বিশ্বে ডিআই এর সাথে সাদৃশ্যপূর্ণ। ধ্রুবক আক্ষরিক পরিবর্তে সেখানে মানগুলি পুরো অবজেক্ট - তবে কোডটি শ্রেণি কোড থেকে তাদের তৈরি করে সরিয়ে দেওয়ার কারণ একই রকম - বস্তুগুলি আরও ঘন ঘন পরিবর্তিত হয় তারপরে কোডটি তাদের ব্যবহার করে। একটি গুরুত্বপূর্ণ ক্ষেত্রে যেখানে এই ধরনের পরিবর্তনের প্রয়োজন তা হ'ল পরীক্ষা।


18
+1 "বস্তুগুলি আরও ঘন ঘন পরিবর্তিত হয় তারপরে কোডগুলি সেগুলি ব্যবহার করে"। জেনারালাইজ করতে, ফ্লাক্সের পয়েন্টে একটি ইন্ডায়ারেশন যুক্ত করুন। প্রবাহের পয়েন্টের উপর নির্ভর করে ইন্ডিয়ারেশনগুলি বিভিন্ন নামে ডাকা হয় !!
চিতান

139

আসুন গাড়ি এবং ইঞ্জিন ক্লাসগুলির সাথে সহজ উদাহরণ চেষ্টা করুন , যে কোনও গাড়ীর কমপক্ষে এখনই যে কোনও জায়গায় যেতে ইঞ্জিন প্রয়োজন। সুতরাং নীচে কীভাবে নির্ভরতা ইনজেকশন ছাড়াই কোড দেখতে পাবেন।

public class Car
{
    public Car()
    {
        GasEngine engine = new GasEngine();
        engine.Start();
    }
}

public class GasEngine
{
    public void Start()
    {
        Console.WriteLine("I use gas as my fuel!");
    }
}

এবং গাড়ী বর্গ ইনস্ট্যান্ট করতে আমরা পরবর্তী কোড ব্যবহার করব:

Car car = new Car();

এই কোডটি নিয়ে সমস্যাটি যা আমরা দৃly়ভাবে গ্যাসজিনে যুক্ত হয়েছি এবং যদি আমরা এটিকে বৈদ্যুতিনজনে পরিবর্তন করার সিদ্ধান্ত নিই তবে আমাদের গাড়ি শ্রেণীর পুনর্লিখনের প্রয়োজন হবে। আর অ্যাপ্লিকেশনটি যত বড় সমস্যা তত বেশি সমস্যা এবং মাথাব্যথা আমাদের নতুন ধরণের ইঞ্জিন যুক্ত করতে এবং ব্যবহার করতে হবে।

অন্য কথায় এই পদ্ধতির সাথে হ'ল আমাদের উচ্চ স্তরের কার শ্রেণি নিম্ন স্তরের গ্যাসEngine শ্রেণীর উপর নির্ভরশীল যা SOLID থেকে নির্ভরতা বিপর্যয় নীতি (ডিআইপি) লঙ্ঘন করে। ডিআইপি পরামর্শ দেয় যে আমাদের কংক্রিট ক্লাস নয়, বিমূর্তির উপর নির্ভর করা উচিত। সুতরাং এটি সন্তুষ্ট করার জন্য আমরা আইংগাইন ইন্টারফেস এবং নীচের মত কোডটি পুনরায় লিখুন:

    public interface IEngine
    {
        void Start();
    }

    public class GasEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I use gas as my fuel!");
        }
    }

    public class ElectricityEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I am electrocar");
        }
    }

    public class Car
    {
        private readonly IEngine _engine;
        public Car(IEngine engine)
        {
            _engine = engine;
        }

        public void Run()
        {
            _engine.Start();
        }
    }

এখন আমাদের গাড়ি শ্রেণিটি কেবল আইংগাইন ইন্টারফেসের উপর নির্ভরশীল, ইঞ্জিনের নির্দিষ্ট প্রয়োগ নয়। এখন, একমাত্র কৌশলটি কীভাবে আমরা গাড়ীর একটি উদাহরণ তৈরি করব এবং এটিকে গ্যাসেনজাইন বা বৈদ্যুতিনজনিত মতো প্রকৃত কংক্রিট ইঞ্জিন শ্রেণি দেব। সেখানেই নির্ভরতা ইনজেকশন আসে।

   Car gasCar = new Car(new GasEngine());
   gasCar.Run();
   Car electroCar = new Car(new ElectricityEngine());
   electroCar.Run();

এখানে আমরা মূলত গাড়ি কনস্ট্রাক্টরের সাথে আমাদের নির্ভরতা (ইঞ্জিনের উদাহরণ) ইনজেক্ট (পাস) করি। সুতরাং এখন আমাদের ক্লাসগুলিতে অবজেক্টস এবং তাদের নির্ভরতার মধ্যে আলগা সংযোগ রয়েছে এবং আমরা সহজেই কার শ্রেণি পরিবর্তন না করে নতুন ধরণের ইঞ্জিন যুক্ত করতে পারি।

ডিপেন্ডেন্সি ইনজেকশনের প্রধান সুবিধা যে ক্লাসগুলি আরও আলগাভাবে মিলিত হয়, কারণ তাদের হার্ড-কোডেড নির্ভরতা নেই। এটি নির্ভরতা বিপরীতমুখী নীতির অনুসরণ করে, যা উপরে উল্লিখিত ছিল। নির্দিষ্ট প্রয়োগগুলি উল্লেখ করার পরিবর্তে, ক্লাসগুলি বিমূর্ততাগুলি (সাধারণত ইন্টারফেস ) অনুরোধ করে যা শ্রেণিটি নির্মাণের পরে তাদের সরবরাহ করা হয়।

সুতরাং শেষ অবধি ইনজেকশন হ'ল বস্তু এবং তাদের নির্ভরতার মধ্যে আলগা সংযোগ অর্জনের জন্য কেবল একটি কৌশল। শ্রেণীর ক্রিয়া সম্পাদনের জন্য যে নির্ভরশীলতাগুলির সরাসরি নির্ভরতা ইনস্ট্যান্ট করে দেওয়ার পরিবর্তে কনস্ট্রাক্টর ইনজেকশন দিয়ে ক্লাসে (প্রায়শই) নির্ভরতা সরবরাহ করা হয়।

এছাড়াও যখন আমাদের অনেক নির্ভরতা থাকে তখন ইনভার্শন অফ কন্ট্রোল (আইওসি) পাত্রে ব্যবহার করা খুব ভাল অনুশীলন যা আমরা বলতে পারি যে আমাদের সমস্ত নির্ভরতার জন্য কংক্রিটের প্রয়োগগুলি কোন ইন্টারফেসকে ম্যাপ করা উচিত এবং আমাদের যখন এটি তৈরি করে তখন আমাদের সেই নির্ভরতাগুলি সমাধান করতে পারি আমাদের অবজেক্ট উদাহরণস্বরূপ, আমরা আইওসি ধারক জন্য ম্যাপিং উল্লেখ করতে পারে যে IEngine নির্ভরতা ম্যাপ দিতে হবে GasEngine বর্গ এবং যখন আমরা আমাদের একজন উদাহরণস্বরূপ আইওসি ধারক জিজ্ঞাসা গাড়ি বর্গ, এটি স্বয়ংক্রিয়ভাবে আমাদের গঠন করা হবে গাড়ি একটি সঙ্গে বর্গ GasEngine নির্ভরতা মধ্যে পাস

আপডেট: সম্প্রতি জুলি লারম্যানের কাছ থেকে ইএফ কোর সম্পর্কে প্রচ্ছন্ন কোর্স এবং ডিআই সম্পর্কে তার সংক্ষিপ্ত সংজ্ঞাটি পছন্দ করেছে।

নির্ভরতা ইনজেকশন হল এমন একটি প্যাটার্ন যা আপনার অ্যাপ্লিকেশনটিকে ফ্লাইতে প্রয়োজনীয় ক্লাসগুলিতে প্রয়োজনীয় বস্তুগুলি ইনজেকশনের অনুমতি দেওয়ার জন্য, সেই ক্লাসগুলিকে সেই বিষয়গুলির জন্য দায়বদ্ধ হতে বাধ্য না করে। এটি আপনার কোডটিকে আরও looseিলেledালাভাবে জুড়তে দেয় এবং সত্ত্বা ফ্রেমওয়ার্ক কোর একই পরিষেবাগুলির এই সিস্টেমে প্লাগ ইন করে।


2
কৌতূহলের বাইরে, কৌশল কৌশল থেকে এটি কীভাবে আলাদা? এই প্যাটার্নটি অ্যালগরিদমগুলিকে আবদ্ধ করে এবং তাদেরকে বিনিময়যোগ্য করে তুলছে। এটি নির্ভর করে যে নির্ভরতা ইনজেকশন এবং কৌশলের ধরণগুলি খুব মিল।
অমৃত

110

আসুন কল্পনা করুন যে আপনি মাছ ধরতে যেতে চান:

  • নির্ভরতা ইনজেকশন ছাড়াই আপনাকে নিজেরাই নিজের যত্ন নেওয়া উচিত। আপনার একটি নৌকা খুঁজে বের করতে হবে, ফিশিং রড কিনতে হবে, টোপ ইত্যাদির সন্ধান করতে হবে এটি অবশ্যই সম্ভব, তবে এটি আপনার উপর অনেক বেশি দায়বদ্ধতা তৈরি করে। সফ্টওয়্যার পদে, এর অর্থ হল যে আপনাকে এই সমস্ত কিছুর জন্য অনুসন্ধান করতে হবে।

  • নির্ভরতা ইনজেকশন সহ, অন্য কেউ সমস্ত প্রস্তুতির যত্ন নেয় এবং প্রয়োজনীয় সরঞ্জাম আপনার জন্য উপলব্ধ করে। আপনি নৌকা, ফিশিং রড এবং টোপ - সমস্ত ব্যবহারের জন্য প্রস্তুত পাবেন ("ইনজেকশনের") পাবেন।


59
ফ্লিপসাইডটি হ'ল, আপনি নিজের বাথরুমটি পুনরায় করতে একটি প্লাম্বার ভাড়া নিয়ে ভাবেন, যিনি তখন বলেছিলেন, "দুর্দান্ত, আমার জন্য আপনার প্রয়োজনীয় সরঞ্জাম ও সামগ্রীর একটি তালিকা এখানে রয়েছে"। প্লাম্বারের কাজটি কি হওয়া উচিত নয়?
jscs

যাতে কারও কারও কারও যত্ন নেওয়া দরকার যার সম্পর্কে জানা ছাড়া এর কোনও ব্যবসা নেই .. তবে তবুও নৌকা, লাঠি এবং টোপ - ব্যবহারের জন্য প্রস্তুত থাকলেও এই তালিকা সংগ্রহ করার সিদ্ধান্ত নেয়।
চুকোস

22
@ জোশক্যাসওয়েল নং, এটি নদীর গভীরতানির্ণয়ের কাজ হবে would ক্লায়েন্ট হিসাবে আপনার নদীর গভীরতানির্ণয় সম্পন্ন করা দরকার। তার জন্য আপনার একটি প্লাম্বার প্রয়োজন। নদীর গভীরতানির্ণয় এর সরঞ্জাম প্রয়োজন। সেগুলি পেতে, এটি নদীর গভীরতানির্ণয় সংস্থা দ্বারা সজ্জিত হয়। একজন ক্লায়েন্ট হিসাবে আপনি প্লাম্বারটি ঠিক কী কী প্রয়োজন তা জানতে চান না। প্লাম্বার হিসাবে আপনি জানেন যা আপনার প্রয়োজন, তবে আপনি কেবল নিজের কাজটি করতে চান, সবকিছু পান না। প্লাস্টিক নিয়োগকারী হিসাবে আপনি আপনার বাড়ির লোকদের বাড়িতে পাঠানোর আগে যা প্রয়োজন তা তাদের সাজানোর জন্য দায়বদ্ধ।
সারা

@ কাই আমি আপনার বক্তব্য বুঝতে পারি। সফটওয়্যারটিতে আমরা একটি কারখানার কথা বলছি, তাই না? কিন্তু ডিআই এরও সাধারণত অর্থ হয় শ্রেণিটি কোনও কারখানা ব্যবহার করে না কারণ এখনও ইঞ্জেকশন করা হয়নি। সরঞ্জামগুলি দেওয়ার জন্য আপনাকে, গ্রাহককে নিয়োগকর্তার (কারখানার) সাথে যোগাযোগ করতে হবে, যাতে আপনি প্লাম্বারে যেতে পারেন। এটি আসলে কোনও প্রোগ্রামে কীভাবে কাজ করবে তা নয়? সুতরাং যখন গ্রাহক (কলিং ক্লাস / ফাংশন / যাই হোক না কেন) সরঞ্জামগুলি সংগ্রহ করতে হবে না, তখনও তাদের মাঝারি লোক হতে হবে তা নিশ্চিত করে তারা এটি নিয়োগকর্তা (কারখানা) থেকে প্লাম্বারে (ইনজেকশন শ্রেণিতে) তৈরি করেছে।
কিংঅফএল ট্রেডস

1
@ কিংঅফএলট্রেডস: অবশ্যই কোনও সময়ে আপনাকে নিয়োগ এবং আউটফিটিং প্ল্যাটফর্ম করতে হবে, অথবা আপনার কোনও প্লাস্টিক নেই। তবে গ্রাহক এটি করছেন না। গ্রাহক কেবল একটি প্লাম্বার জন্য জিজ্ঞাসা করেন, এবং তার কাজটি করার জন্য যা প্রয়োজন তার সাথে এটি ইতিমধ্যে সজ্জিত হয়ে যায়। ডিআই সহ, আপনার অবশেষে নির্ভরতাগুলি পূরণ করার জন্য কিছু কোড রয়েছে। তবে আপনি এটিকে কোড থেকে আলাদা করছেন যা আসল কাজ করে। আপনি যদি এটির পরিপূর্ণ পরিসরে নিয়ে যান, আপনার বস্তুগুলি কেবল তাদের নির্ভরশীলতাগুলি পরিচিত করে তোলে এবং অবজেক্ট-গ্রাফ-বিল্ডিং বাইরে প্রায়শই ইন ডি কোডে ঘটে।
সিএওও

102

এই সম্পর্কে সবচেয়ে সহজ ব্যাখ্যা নির্ভরতা ইনজেকশন এবং নির্ভরতা ইনজেকশন কনটেইনার আমার দেখা হয়েছে:

নির্ভরতা ইনজেকশন ছাড়াই

  • অ্যাপ্লিকেশনটির ফু প্রয়োজন (যেমন একটি নিয়ামক), তাই:
  • অ্যাপ্লিকেশন ফু তৈরি করে
  • অ্যাপ্লিকেশন কল Foo
    • ফু এর বার দরকার (যেমন একটি পরিষেবা), সুতরাং:
    • ফু তৈরি করে বার
    • ফু ফোন বার
      • বারের জন্য বিমের প্রয়োজন (একটি পরিষেবা, একটি ভান্ডার,…), ​​সুতরাং:
      • বার বিম তৈরি করে
      • বার কিছু করে

নির্ভরতা ইনজেকশন সহ

  • অ্যাপ্লিকেশনটির জন্য ফু প্রয়োজন, যার বার প্রয়োজন, যার বিম প্রয়োজন, তাই:
  • অ্যাপ্লিকেশন বিম তৈরি করে
  • অ্যাপ্লিকেশন বার তৈরি করে এবং এটি বিম দেয়
  • অ্যাপ্লিকেশন ফু তৈরি করে এবং এটি বার দেয়
  • অ্যাপ্লিকেশন কল Foo
    • ফু ফোন বার
      • বার কিছু করে

একটি নির্ভরতা ইনজেকশন ধারক ব্যবহার করে

  • অ্যাপ্লিকেশনটির ফুও দরকার:
  • অ্যাপ্লিকেশন কনটেইনার থেকে ফু পায়, সুতরাং:
    • ধারক বিম তৈরি করে
    • ধারক বার তৈরি করে এবং এটি বিম দেয়
    • পাত্রে ফু তৈরি করে এবং এটি বার দেয়
  • অ্যাপ্লিকেশন কল Foo
    • ফু ফোন বার
      • বার কিছু করে

নির্ভরতা ইনজেকশন এবং নির্ভরতা ইনজেকশন ধারকগুলি পৃথক জিনিস:

  • নির্ভরশীল ইনজেকশন আরও ভাল কোড লেখার জন্য একটি পদ্ধতি
  • একটি ডিআই কনটেইনার হ'ল একটি সরঞ্জাম যা ইনজেকশন নির্ভরতাগুলিতে সহায়তা করে

নির্ভরতা ইঞ্জেকশন করার জন্য আপনার ধারক লাগবে না। তবে একটি ধারক আপনাকে সহায়তা করতে পারে।



55

"নির্ভরতা ইনজেকশন" এর অর্থ কি প্যারামিটারাইজড কনস্ট্রাক্টর এবং পাবলিক সেটারগুলি ব্যবহার করে না?

জেমস শোরের নিবন্ধটি তুলনার জন্য নিম্নলিখিত উদাহরণগুলি দেখায়

নির্ভরতা ইনজেকশন ছাড়াই নির্মাণকারী:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
} 

নির্ভরতা ইনজেকশন সহ নির্মাতা:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
}

অবশ্যই ডিআই সংস্করণে আপনি কোনও আর্গুমেন্ট কনস্ট্রাক্টরে মাই ডেটাবেস অবজেক্টটি আরম্ভ করতে চান না? কোনও লাভ নেই বলে মনে হচ্ছে এবং যদি আপনি ওভারলোডেড কনস্ট্রাক্টরকে ফোন না করে ডস্টফকে কল করার চেষ্টা করেন তবে ব্যতিক্রম করতে চান?
ম্যাট উইলকো

কেবলমাত্র যদি new DatabaseThingie()কোনও বৈধ মাই ডেটাবেস উদাহরণ তৈরি করে না।
জেনগুডাল

40

নির্ভরতা ইনজেকশন ধারণাটি সহজ করে তোলা। আসুন একটি বাল্ব টগল করতে (চালু / বন্ধ) করতে স্যুইচ বাটনটির একটি উদাহরণ নেওয়া যাক।

নির্ভরতা ইনজেকশন ছাড়াই

আমি কোন বাল্বের সাথে সংযুক্ত রয়েছি তা আগেই জানতে হবে (হার্ড-কোডেড নির্ভরতা)। সুতরাং,

স্যুইচ করুন -> স্থায়ী বাল্ব // সুইচটি স্থায়ী বাল্বের সাথে সরাসরি সংযুক্ত থাকে, পরীক্ষার কাজটি সহজেই সম্ভব হয় না

Switch(){
PermanentBulb = new Bulb();
PermanentBulb.Toggle();
}

নির্ভরতা ইনজেকশন সহ

স্যুইচ করুন কেবল জানেন যে আমার কাছে যে কোনও বাল্ব পাস হবে তা আমাকে চালু / বন্ধ করতে হবে। সুতরাং,

স্যুইচ করুন -> বাল্ব 1 বা বাল্ব 2 বা নাইটবুলব (ইনজেকশন নির্ভরতা)

Switch(AnyBulb){ //pass it whichever bulb you like
AnyBulb.Toggle();
}

সুইচ এবং বাল্বের জন্য জেমস উদাহরণটি সংশোধন করা :

public class SwitchTest { 
  TestToggleBulb() { 
    MockBulb mockbulb = new MockBulb(); 

    // MockBulb is a subclass of Bulb, so we can 
    // "inject" it here: 
    Switch switch = new Switch(mockBulb); 

    switch.ToggleBulb(); 
    mockBulb.AssertToggleWasCalled(); 
  } 
}

public class Switch { 
  private Bulb myBulb; 

  public Switch() { 
    myBulb = new Bulb(); 
  } 

  public Switch(Bulb useThisBulbInstead) { 
    myBulb = useThisBulbInstead; 
  } 

  public void ToggleBulb() { 
    ... 
    myBulb.Toggle(); 
    ... 
  } 
}`

36

নির্ভরতা ইনজেকশন (ডিআই) কী?

যেমনটি অন্যেরা বলেছেন, ডিপেন্ডেন্সি ইনজেকশন (ডিআই) অন্যান্য বস্তুর উদাহরণগুলির উপর নির্ভর করে যেখানে আমাদের আগ্রহের শ্রেণি (গ্রাহক শ্রেণি) নির্ভর করে ( ইউএমএল অর্থে ) তার সরাসরি জীবনধারণ এবং পরিচালনা করার দায়িত্ব সরিয়ে দেয় । এই উদাহরণগুলি পরিবর্তে আমাদের কনজিউমার ক্লাসে পৌঁছে দেওয়া হয়, সাধারণত কনস্ট্রাক্টর প্যারামিটার হিসাবে বা সম্পত্তি সেটারের মাধ্যমে (নির্ভরতা অবজেক্টের পরিচালনা এবং গ্রাহক শ্রেণিতে পাস করা সাধারণত নিয়ন্ত্রণের একটি ইনভার্শন (আইওসি) ধারক দ্বারা সম্পাদিত হয় তবে এটি অন্য বিষয়) ।

ডিআই, ডিআইপি এবং সলিড

বিশেষ করে, রবার্ট সি মার্টিন এর দৃষ্টান্ত মধ্যে ওরিয়েন্টড ডিজাইন বস্তু কঠিন নীতি , DIসম্ভাব্য বাস্তবায়নের অন্যতম নির্ভরতা ইনভার্সান নীতি (চোবান)চোবান আছে Dএর SOLIDমন্ত্রকে অন্যান্য চোবান বাস্তবায়নের পরিষেবা লোকেটার এবং প্লাগইন নিদর্শন অন্তর্ভুক্ত -।

ডিআইপি'র উদ্দেশ্য ক্লাসের মধ্যে শক্ত, কংক্রিট নির্ভরতা ডিক্লোল করা এবং পরিবর্তে, একটি বিমূর্ততার মাধ্যমে মিলিতকরণকে আলগা করা, যা ব্যবহার করা ভাষা এবং পদ্ধতির উপর নির্ভর করে interface, abstract classবা দ্বারা অর্জন করা যেতে পারে pure virtual class

ডিআইপি ব্যতীত, আমাদের কোড (আমি এই 'গ্রাহক শ্রেণি' বলেছি) সরাসরি একটি কংক্রিট নির্ভরতার সাথে মিলিত হয় এবং প্রায়শই এই নির্ভরতার উদাহরণ, যেমন ধারণাগতভাবে কীভাবে প্রাপ্ত এবং পরিচালনা করতে হয় তা জানার দায়িত্বের সাথে বোঝা থাকে:

"I need to create/use a Foo and invoke method `GetBar()`"

যেখানে ডিআইপি প্রয়োগের পরে প্রয়োজনীয়তাটি শিথিল করা হয় এবং Fooনির্ভরতার আয়ু অর্জন ও পরিচালনার উদ্বেগ অপসারণ করা হয়:

"I need to invoke something which offers `GetBar()`"

ডিআইপি (এবং ডিআই) কেন ব্যবহার করবেন?

শ্রেণিগুলির মধ্যে এইভাবে নির্ভরতাগুলি ডিকুলিংয়ের ফলে অন্যান্য বাস্তবায়নগুলির সাথে এই নির্ভরশীলতা শ্রেণীর সহজে প্রতিস্থাপনের সুযোগ দেয় যা বিমূর্তির পূর্বশর্তগুলিও পূরণ করে (যেমন নির্ভরতা একই ইন্টারফেসের অন্য প্রয়োগের সাথে বদলানো যেতে পারে)। অধিকন্তু, অন্যদের উল্লেখ করেছি, সম্ভবত চোবান মাধ্যমে decouple ক্লাস সবচেয়ে সাধারণ কারণ সর্বগ্রাসী বর্গ, বিচ্ছিন্নতা পরীক্ষিত করা যেমন এই একই নির্ভরতা এখন stubbed করা যেতে পারে এবং / অথবা ব্যঙ্গ অনুমতি দিতে হয়।

ডিআই-এর একটি পরিণতি হ'ল নির্ভরতা অবজেক্টের দৃষ্টান্তগুলির জীবনকাল পরিচালনা আর কোনও গ্রাহক শ্রেণীর দ্বারা নিয়ন্ত্রণ করা হয় না, কারণ নির্ভরতা অবজেক্টটি এখন গ্রাহক শ্রেণিতে (কনস্ট্রাক্টর বা সেটার ইনজেকশনের মাধ্যমে) পাস করা হয়।

এটি বিভিন্ন উপায়ে দেখা যায়:

  • গ্রাহক শ্রেণীর নির্ভরতাগুলির আজীবন নিয়ন্ত্রণ যদি বজায় রাখা দরকার হয় তবে ভোক্তা শ্রেণিতে নির্ভরতা শ্রেণির উদাহরণ তৈরির জন্য একটি (বিমূর্ত) কারখানা ইনজেকশনের মাধ্যমে নিয়ন্ত্রণ পুনরায় প্রতিষ্ঠিত করা যেতে পারে। গ্রাহক Createপ্রয়োজন অনুসারে কারখানায় কারখানার মাধ্যমে উদাহরণগুলি অর্জন করতে সক্ষম হবেন এবং এই দৃষ্টান্তগুলি সম্পূর্ণ হয়ে গেলে তা নিষ্পত্তি করতে সক্ষম হবেন ।
  • বা, নির্ভরতা উদাহরণগুলির আজীবন নিয়ন্ত্রণ আইওসি ধারকটিতে ছেড়ে দেওয়া যেতে পারে (নীচে এটি সম্পর্কে আরও)।

ডিআই কখন ব্যবহার করবেন?

  • সমতুল্য বাস্তবায়নের জন্য যেখানে নির্ভরতা স্থাপনের প্রয়োজন হতে পারে,
  • যে কোনও সময় যেখানে আপনার শ্রেণিটির নির্ভরতাগুলি বিচ্ছিন্ন করার পদ্ধতিগুলি পরীক্ষা করার প্রয়োজন হবে,
  • নির্ভরতার জীবনকাল সম্পর্কে অনিশ্চয়তা পরীক্ষা-নিরীক্ষার নিশ্চয়তা দিতে পারে (যেমন, হ্যাঁ MyDepClass, থ্রেড নিরাপদ - যদি আমরা এটিকে একটি সিঙ্গলটন হিসাবে তৈরি করি এবং সমস্ত গ্রাহকের মধ্যে একই উদাহরণটি ইনজেকশন করি?)

উদাহরণ

এখানে একটি সাধারণ সি # বাস্তবায়ন। নীচে গ্রাহক শ্রেণি দেওয়া:

public class MyLogger
{
   public void LogRecord(string somethingToLog)
   {
      Console.WriteLine("{0:HH:mm:ss} - {1}", DateTime.Now, somethingToLog);
   }
}

যদিও আপাতদৃষ্টিতে নির্দোষ মনে হচ্ছে, এটি staticঅন্য দুটি শ্রেণীর উপর দুটি নির্ভরশীলতা রয়েছে System.DateTimeএবং System.Consoleএটি কেবল লগিং আউটপুট বিকল্পগুলিকে সীমাবদ্ধ করে না (কনসোলে লগিং যদি কেউ দেখছে না তবে মূল্যহীন হবে), তবে আরও খারাপ, এর উপর নির্ভরতা দেখিয়ে স্বয়ংক্রিয়ভাবে পরীক্ষা করা কঠিন is একটি অ-নিরস্তক সিস্টেম ঘড়ি।

DIPনির্ভরতা হিসাবে টাইমস্ট্যাম্পিংয়ের উদ্বেগকে বাদ দিয়ে এবং MyLoggerকেবল একটি সাধারণ ইন্টারফেসে সংযুক্ত করে আমরা এই শ্রেণিতে প্রয়োগ করতে পারি :

public interface IClock
{
    DateTime Now { get; }
}

আমরা Consoleএকটি বিমূর্তের উপর নির্ভরতা আলগা করতে পারি , যেমন এ TextWriter। নির্ভরতা ইনজেকশন সাধারণত হয় constructorইনজেকশন হিসাবে প্রয়োগ করা হয় (গ্রাহক শ্রেণীর নির্মাতার কাছে প্যারামিটার হিসাবে নির্ভরতা একটি বিমূর্ততা পাস) বা Setter Injection(একটি setXyz()সেটারের মাধ্যমে নির্ভরতা পাস বা একটি {set;}সংজ্ঞায়িত নেট সম্পত্তি )। কনস্ট্রাক্টর ইঞ্জেকশনটিকে অগ্রাধিকার দেওয়া হয়েছে, কারণ এটি গ্যারান্টি দেয় যে নির্মাণের পরে শ্রেণিটি সঠিক অবস্থায় থাকবে এবং অভ্যন্তরীণ নির্ভরতা ক্ষেত্রগুলিকে readonly(সি #) বা final(জাভা) হিসাবে চিহ্নিত করার অনুমতি দেয় । সুতরাং উপরের উদাহরণে কন্সট্রাক্টর ইঞ্জেকশন ব্যবহার করে এটি আমাদের সাথে ছেড়ে দেয়:

public class MyLogger : ILogger // Others will depend on our logger.
{
    private readonly TextWriter _output;
    private readonly IClock _clock;

    // Dependencies are injected through the constructor
    public MyLogger(TextWriter stream, IClock clock)
    {
        _output = stream;
        _clock = clock;
    }

    public void LogRecord(string somethingToLog)
    {
        // We can now use our dependencies through the abstraction 
        // and without knowledge of the lifespans of the dependencies
        _output.Write("{0:yyyy-MM-dd HH:mm:ss} - {1}", _clock.Now, somethingToLog);
    }
}

(একটি কংক্রিট সরবরাহ করা Clockদরকার, অবশ্যই DateTime.Nowকোনটিতে ফিরে যেতে পারে এবং দুটি নির্ভরতা আইওসি ধারক দ্বারা কনস্ট্রাক্টর ইনজেকশনের মাধ্যমে সরবরাহ করা প্রয়োজন)

একটি স্বয়ংক্রিয় ইউনিট পরীক্ষা তৈরি করা যেতে পারে, যা নিশ্চিতভাবে প্রমাণ করে যে আমাদের লগার সঠিকভাবে কাজ করছে, যেহেতু এখন আমাদের নির্ভরতা - সময়ের উপর নিয়ন্ত্রণ রয়েছে এবং আমরা লিখিত আউটপুটটিতে নজর রাখতে পারি:

[Test]
public void LoggingMustRecordAllInformationAndStampTheTime()
{
    // Arrange
    var mockClock = new Mock<IClock>();
    mockClock.Setup(c => c.Now).Returns(new DateTime(2015, 4, 11, 12, 31, 45));
    var fakeConsole = new StringWriter();

    // Act
    new MyLogger(fakeConsole, mockClock.Object)
        .LogRecord("Foo");

    // Assert
    Assert.AreEqual("2015-04-11 12:31:45 - Foo", fakeConsole.ToString());
}

পরবর্তী পদক্ষেপ

নির্ভরতা ইনজেকশন অবিচ্ছিন্নভাবে নিয়ন্ত্রণের ধারক ইনভার্শন (আইওসি) এর সাথে , কংক্রিটের নির্ভরতা উদাহরণগুলি সরবরাহ করতে এবং আজীবন দৃষ্টান্তগুলি পরিচালনা করার সাথে যুক্ত থাকে manage কনফিগারেশন / বুটস্ট্র্যাপিং প্রক্রিয়া চলাকালীন, ধারকগুলি IoCনিম্নলিখিতগুলি সংজ্ঞায়িত করার অনুমতি দেয়:

  • প্রতিটি বিমূর্তি এবং কনফিগার করা কংক্রিট প্রয়োগের মধ্যে ম্যাপিং (উদাঃ "যে কোনও সময় কোনও গ্রাহক অনুরোধ করেন IBar, ConcreteBarউদাহরণ ফেরৎ " )
  • প্রতিটি পরাধীনতার জীবনকাল পরিচালনার জন্য নীতিগুলি সেট আপ করা যায়, যেমন প্রতিটি গ্রাহকের উদাহরণের জন্য একটি নতুন অবজেক্ট তৈরি করা, সমস্ত গ্রাহকের মধ্যে একটি একক নির্ভরতা উদাহরণ ভাগ করে নেওয়া, একই নির্ভরতার উদাহরণটি একই থ্রেডের মধ্যে ভাগ করে নেওয়া ইত্যাদি etc.
  • নেট, আইওসি পাত্রে যেমন প্রোটোকল সম্পর্কে সচেতন IDisposableএবং তা Disposingকনফিগার করা জীবনকাল পরিচালনার সাথে সামঞ্জস্য রেখে নির্ভরতাগুলির দায়িত্ব নেবে ।

সাধারণত, একবার আইওসি পাত্রে কনফিগার করা / বুটস্ট্র্যাপ করা হয়ে গেলে, তারা পটভূমিতে নির্বিঘ্নে কাজ করে কোডারকে নির্ভরতার বিষয়ে চিন্তা করার চেয়ে হাতের কোডটিতে ফোকাস করতে দেয়।

ডিআই-বান্ধব কোডের মূলটি হ'ল ক্লাসগুলির স্থির মিলন এড়ানো এবং নির্ভরতা তৈরির জন্য নতুন () ব্যবহার না করা

উপরোক্ত উদাহরণ অনুসারে, নির্ভরতাগুলি ডিকুয়াল করার জন্য কিছু নকশার প্রচেষ্টা প্রয়োজন হয় এবং বিকাশকারীদের জন্য newসরাসরি নির্ভরশীলতাগুলির অভ্যাসটি ভাঙার জন্য একটি প্যারাডিম শিফট দরকার হয় এবং পরিবর্তে নির্ভরতা পরিচালনার জন্য ধারকটির উপর নির্ভর করে।

তবে সুবিধাগুলি অনেকগুলি, বিশেষত আপনার আগ্রহের শ্রেণীর পুরোপুরি পরীক্ষা করার দক্ষতায়।

দ্রষ্টব্য : new ..()POCO / POJO / সিরিয়ালাইজেশন DTOs / সত্তা গ্রাফ / বেনামে JSON প্রজেকশন এবং অন্যান্য - যেমন "কেবলমাত্র ডেটা" শ্রেণি বা রেকর্ড - পদ্ধতি থেকে ব্যবহৃত বা প্রত্যাশিত - তৈরি বা ম্যাপিং / প্রজেকশন (মাধ্যমে ) নির্ভরতা হিসাবে বিবেচিত হয় না ( ইউএমএল ইন্দ্রিয়) এবং ডিআই সাপেক্ষে নয়। newএগুলি প্রজেক্ট করতে ব্যবহার করা ঠিক আছে।


1
সমস্যাটি ডিআইপি! = ডিআই। ডিআইপি বাস্তবায়ন থেকে বিমূর্ততা ডিউপলিং সম্পর্কে: উ: উচ্চ-স্তরের মডিউলগুলি নিম্ন-স্তরের মডিউলগুলির উপর নির্ভর করে না। উভয়ের বিমূর্ততা উপর নির্ভর করা উচিত। খ। বিমূর্ততা বিশদ উপর নির্ভর করবে না। বিবরণ বিমূর্ততা উপর নির্ভর করা উচিত। ডিআই হ'ল অবজেক্ট ব্যবহার থেকে অবজেক্টের সৃষ্টি ডিকোপল করার একটি উপায়।
রিকার্ডো রিভালদো

হ্যাঁ, আঙ্কেল ববসের সলিউড দৃষ্টান্তে আমার অনুচ্ছেদ 2, "ডিআইপি-র সম্ভাব্য বাস্তবায়নের মধ্যে একটি অন্যতম" স্পষ্ট করে এই পার্থক্যটি স্পষ্টভাবে বর্ণিত হয়েছে । আমি এটি আগের পোস্টেও পরিষ্কার করে দিয়েছি ।
স্টুয়ার্টএলসি 16'17

25

নির্ভরতা ইনজেকশন (ডিআই) এর পুরো পয়েন্টটি হ'ল অ্যাপ্লিকেশন উত্স কোডটি পরিষ্কার এবং স্থিতিশীল রাখতে হবে :

  • নির্ভরতা সূচনা কোড পরিষ্কার
  • নির্ভরতা নির্বিশেষে ব্যবহৃত স্থিতিশীল

ব্যবহারিকভাবে, প্রতিটি নকশার প্যাটার্নটি ভবিষ্যতে ন্যূনতম ফাইলগুলিকে প্রভাবিত করতে উদ্বেগকে পৃথক করে।

ডিআই-এর নির্দিষ্ট ডোমেন নির্ভরতা কনফিগারেশন এবং ইনিশিয়ালাইজেশনের প্রতিনিধি।

উদাহরণ: ডিআই শেল স্ক্রিপ্ট সহ

আপনি যদি মাঝে মাঝে জাভার বাইরে কাজ করেন তবে মনে করুন কীভাবে sourceপ্রায়শই অনেক স্ক্রিপ্টিং ভাষায় ব্যবহৃত হয় (শেল, টিসিএল ইত্যাদি, বা importপাইথনের এমনকি এই উদ্দেশ্যে অপব্যবহার করা হয়)।

সাধারণ dependent.shস্ক্রিপ্ট বিবেচনা করুন :

#!/bin/sh
# Dependent
touch         "one.txt" "two.txt"
archive_files "one.txt" "two.txt"

স্ক্রিপ্টটি নির্ভরশীল: এটি নিজেরাই সফলভাবে কার্যকর হবে না ( archive_filesসংজ্ঞায়িত নয়)।

আপনি সংজ্ঞায়িত archive_filesমধ্যে archive_files_zip.shবাস্তবায়ন স্ক্রিপ্ট (ব্যবহার zipএই ক্ষেত্রে):

#!/bin/sh
# Dependency
function archive_files {
    zip files.zip "$@"
}

sourceসরাসরি নির্ভরশীল স্ক্রিপ্টে বাস্তবায়ন স্ক্রিপ্টের পরিবর্তে , আপনি একটি injector.sh"ধারক" ব্যবহার করেন যা উভয় "উপাদান" কে আবৃত করে:

#!/bin/sh 
# Injector
source ./archive_files_zip.sh
source ./dependent.sh

archive_files নির্ভরতা মাত্র হয়েছে ইনজেকশনের মধ্যে নির্ভরশীল স্ক্রিপ্ট।

আপনি ইনজেকশন নির্ভরতা থাকতে পারে যা archive_filesব্যবহার করে tarবা প্রয়োগ করে xz

উদাহরণ: ডিআই সরিয়ে ফেলা হচ্ছে

যদি dependent.shস্ক্রিপ্টটি সরাসরি নির্ভরতা ব্যবহার করে, তবে পদ্ধতিকে নির্ভরতা লুকআপ বলা হবে (যা নির্ভরতা ইনজেকশনের বিপরীতে ):

#!/bin/sh
# Dependent

# dependency look-up
source ./archive_files_zip.sh

touch         "one.txt" "two.txt"
archive_files "one.txt" "two.txt"

এখন সমস্যাটি নির্ভর করে যে "নির্ভরযোগ্য" উপাদানটি নিজেই আরম্ভ করতে হবে।

"উপাদান" এর উত্স কোডটিও পরিষ্কার বা স্থিতিশীল নয় কারণ নির্ভরতাগুলির প্রাথমিককরণের প্রতিটি পরিবর্তনের জন্য "উপাদানগুলির" উত্স কোড ফাইলের জন্যও নতুন রিলিজ দরকার।

শেষ কথা

জাভা ফ্রেমওয়ার্কগুলিতে ডিআই তেমন জোর দেওয়া এবং জনপ্রিয় নয়।

তবে উদ্বেগগুলির বিভাজনের জন্য এটি একটি সাধারণ পদ্ধতি:

  • অ্যাপ্লিকেশন বিকাশ ( একক উত্স কোড রিলিজ জীবনকাল)
  • অ্যাপ্লিকেশন স্থাপনা ( স্বতন্ত্র লাইফসাইকেলের সাথে একাধিক লক্ষ্য পরিবেশ)

শুধুমাত্র নির্ভরতা অনুসন্ধানের সাথে কনফিগারেশন ব্যবহার করা সহায়ক নয় কারণ কনফিগারেশন প্যারামিটারগুলির সংখ্যা নির্ভরতা (যেমন নতুন প্রমাণীকরণের ধরণ) পাশাপাশি নির্ভরযোগ্যতার সমর্থিত ধরণের সংখ্যা (যেমন নতুন ডাটাবেস টাইপ) পরিবর্তিত হতে পারে help


ডিআই-এর উদ্দেশ্য হিসাবে আমি কোনও নির্দিষ্ট শ্রেণি (পরীক্ষা) সম্পন্ন করার দক্ষতা যুক্ত করব।
ডেভিড

22

উপরের সমস্ত উত্তরগুলি ভাল, আমার উদ্দেশ্যটি একটি সহজ পদ্ধতিতে ধারণাটি ব্যাখ্যা করা যাতে প্রোগ্রামিং জ্ঞান না থাকা যে কেউ ধারণাটি বুঝতে পারে

নির্ভরতা ইনজেকশন হ'ল ডিজাইন প্যাটার্নগুলির মধ্যে একটি যা আমাদের সহজ পদ্ধতিতে জটিল সিস্টেমগুলি তৈরি করতে সহায়তা করে।

আমরা আমাদের প্রতিদিনের জীবনে এই প্যাটার্নটির বিস্তৃত প্রয়োগ দেখতে পাই। কয়েকটি উদাহরণ টেপ রেকর্ডার, ভিসিডি, সিডি ড্রাইভ ইত্যাদি are

রিল টু রিল পোর্টেবল টেপ রেকর্ডার, 20-শতাব্দীর মাঝামাঝি।

উপরের চিত্রটি 20 ম শতাব্দীর মধ্যভাগে রিল-টু রিল পোর্টেবল টেপ রেকর্ডারের একটি চিত্র। উত্স

কোনও টেপ রেকর্ডার মেশিনের প্রাথমিক উদ্দেশ্য হ'ল রেকর্ড করা বা প্লেব্যাক শব্দ।

একটি সিস্টেম ডিজাইন করার সময় এটি রিল করতে বা প্লেব্যাক শব্দ বা সঙ্গীত জন্য একটি রিল প্রয়োজন। এই সিস্টেমটি ডিজাইনের জন্য দুটি সম্ভাবনা রয়েছে

  1. আমরা মেশিনের ভিতরে রিল রাখতে পারি
  2. আমরা যেখানে রিল রাখতে পারি সেখানে একটি হুক সরবরাহ করতে পারি।

আমরা যদি প্রথমটি ব্যবহার করি তবে আমাদের রিল পরিবর্তন করতে মেশিনটি খুলতে হবে। যদি আমরা দ্বিতীয়টির জন্য বেছে নিই, এটি রেলের জন্য একটি হুক রাখছে, আমরা রিলটি পরিবর্তন করে যে কোনও সঙ্গীত বাজানোর একটি অতিরিক্ত সুবিধা পাচ্ছি। এবং ফাংশন হ্রাস শুধুমাত্র রিল যা কিছু খেলতে।

বুদ্ধিমান নির্ভরতা ইনজেকশনটি হ'ল নির্ভরতাগুলি বাহ্যিককরণের প্রক্রিয়াটি কেবলমাত্র উপাদানটির নির্দিষ্ট কার্যকারিতাটিতে ফোকাস করার জন্য যাতে স্বাধীন উপাদানগুলি একত্রিত করে একটি জটিল সিস্টেম গঠন করতে পারে।

নির্ভরতা ইনজেকশন ব্যবহার করে আমরা প্রধান লাভগুলি।

  • উচ্চ সংহতি এবং আলগা সংযোগ।
  • বাহ্যিক নির্ভরতা এবং কেবল দায়বদ্ধতার দিকে তাকানো।
  • উপাদান হিসাবে উপাদান তৈরি এবং উচ্চ ক্ষমতা সহ একটি বৃহত সিস্টেম গঠন একত্রিত করা।
  • এটি উচ্চমানের উপাদানগুলি বিকাশ করতে সহায়তা করে যেহেতু তারা স্বতন্ত্রভাবে বিকশিত হয় সেগুলি সঠিকভাবে পরীক্ষা করা হয়।
  • এটি ব্যর্থ হলে উপাদানটিকে অন্যটির সাথে প্রতিস্থাপন করতে সহায়তা করে।

এখন একটি দিন এই ধারণাগুলি প্রোগ্রামিং জগতের সুপরিচিত ফ্রেমওয়ার্কগুলির ভিত্তি তৈরি করে। স্প্রিং অ্যাংুলার ইত্যাদি হ'ল এই ধারণার শীর্ষে নির্মিত সুপরিচিত সফ্টওয়্যার ফ্রেমওয়ার্ক

নির্ভরতা ইনজেকশন এমন একটি প্যাটার্ন যা অবজেক্টগুলির উদাহরণ তৈরি করতে ব্যবহৃত হয় যা অন্যান্য বিষয়গুলি সংকলনকালে না জানার কারণে নির্ভর করে যে কোন শ্রেণিটি সেই কার্যকারিতা সরবরাহ করতে ব্যবহৃত হবে বা কোনও বস্তুতে কেবল বৈশিষ্ট্য ইনজেকশনের উপায়কে নির্ভরতা ইনজেকশন বলে called

নির্ভরতা ইনজেকশন জন্য উদাহরণ

আগে আমরা এই জাতীয় কোড লিখছি

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

নির্ভরতা ইনজেকশন সহ, নির্ভরতা ইনজেক্টর আমাদের জন্য ইনস্ট্যান্টেশনটি সরিয়ে ফেলবে

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

আপনি পড়তে পারেন

নিয়ন্ত্রণ এবং নির্ভরতা ইনজেকশন এর বিপরীতে পার্থক্য


17

নির্ভরতা ইনজেকশন কী?

নির্ভরতা ইনজেকশন (ডিআই) এর অর্থ একে অপরের উপর নির্ভরশীল অবজেক্টগুলি ডিকুয়াল করা। বলুন অবজেক্ট এ অবজেক্ট বি এর উপর নির্ভরশীল তাই ধারণা এই বিষয়টিকে একে অপরের থেকে ডিকুয়াল করে। সংকলনের সময় সত্ত্বেও রানটাইমে অবজেক্টের সাথে নির্ভরতা ভাগ করে নেওয়ার পরিবর্তে আমাদের নতুন কীওয়ার্ড ব্যবহার করে অবজেক্টটির হার্ড কোড করার দরকার নেই। আমরা যদি কথা বলি

বসন্তে নির্ভরতা ইনজেকশন কীভাবে কাজ করে:

কনফিগারেশন ফাইলে শিমের নির্ভরতা নির্ধারণ করার পরিবর্তে আমাদের নতুন কীওয়ার্ড ব্যবহার করে অবজেক্টটির হার্ড কোড করার দরকার নেই। স্প্রিং পাত্রে সমস্ত হুক আপ জন্য দায়ী করা হবে।

বিপরীতকরণের নিয়ন্ত্রণ (আইওসি)

আইওসি একটি সাধারণ ধারণা এবং এটি বিভিন্ন উপায়ে প্রকাশ করা যায় এবং নির্ভরতা ইনজেকশন আইওসির একটি দৃ concrete় উদাহরণ is

নির্ভরতা ইনজেকশন দুই ধরণের:

  1. কনস্ট্রাক্টর ইনজেকশন
  2. সেটার ইনজেকশন

1. কনস্ট্রাক্টর ভিত্তিক নির্ভরতা ইনজেকশন:

কনট্রাক্টর-ভিত্তিক ডিআই সম্পন্ন হয় যখন কনটেইনারটি অনেকগুলি যুক্তি সহ একটি শ্রেণি নির্মাতাকে আমন্ত্রণ জানায়, প্রত্যেকে অন্য শ্রেণীর উপর নির্ভরশীলতার প্রতিনিধিত্ব করে।

public class Triangle {

private String type;

public String getType(){
    return type;
 }

public Triangle(String type){   //constructor injection
    this.type=type;
 }
}
<bean id=triangle" class ="com.test.dependencyInjection.Triangle">
        <constructor-arg value="20"/>
  </bean>

2. সেটার-ভিত্তিক নির্ভরতা ইনজেকশন:

আপনার শিমটি ইনস্ট্যান্ট করার জন্য নো-আর্গুমেন্ট কনস্ট্রাক্টর বা নো-আর্গুমেন্ট স্ট্যাটিক ফ্যাক্টরি পদ্ধতিটি চাওয়ার পরে সেটার-ভিত্তিক ডিআই আপনার বিনগুলিতে ধারক কলিং সেটার পদ্ধতিগুলি দ্বারা সম্পন্ন হয়।

public class Triangle{

 private String type;

 public String getType(){
    return type;
  }
 public void setType(String type){          //setter injection
    this.type = type;
  }
 }

<!-- setter injection -->
 <bean id="triangle" class="com.test.dependencyInjection.Triangle">
        <property name="type" value="equivialteral"/>

দ্রষ্টব্য: বাধ্যতামূলক নির্ভরতা এবং alচ্ছিক নির্ভরতার জন্য সেটটারগুলির জন্য কনস্ট্রাক্টর আর্গুমেন্ট ব্যবহার করা থাম্বের একটি ভাল নিয়ম। মনে রাখবেন যে আমরা যদি কোনও সেটারে @ প্রয়োজনীয় টীকাগুলির চেয়ে বেশি টিকা ব্যবহার করি তবে প্রয়োজনীয় নির্ভরতা হিসাবে সেটারগুলি তৈরি করতে ব্যবহার করা যেতে পারে।


15

অপারেশন থিয়েটারে সার্জন এবং তার সহকারী (গুলি) সম্পর্কে আমি সবচেয়ে ভাল উপমাটি ভাবতে পারি, যেখানে সার্জন হলেন মূল ব্যক্তি এবং তার সহকারী যিনি যখন প্রয়োজন হয় তখন বিভিন্ন শল্য চিকিত্সা সরবরাহ করেন যাতে সার্জন একজনের প্রতি মনোনিবেশ করতে পারে জিনিস তিনি সেরা করেন (সার্জারি)। সহকারী ব্যতীত সার্জনকে প্রতিটি সময় তার প্রয়োজন মতো উপাদানগুলি নিজেই পেতে হয়।

সংক্ষেপে ডিআই, নির্ভরযোগ্য উপাদানগুলি আনার জন্য উপাদানগুলির উপর একটি সাধারণ অতিরিক্ত দায়িত্ব (বোঝা) অপসারণ করার কৌশল a

ডিআই আপনাকে একক দায়িত্বের (এসআর) নীতিটির কাছাকাছি নিয়ে আসে surgeon who can concentrate on surgery

কখন ডিআই ব্যবহার করবেন: আমি প্রায় সমস্ত উত্পাদন প্রকল্পে (ছোট / বড়) ডিআই ব্যবহার করার পরামর্শ দেব, বিশেষত ব্যবসায়িক পরিবেশ পরিবর্তনের ক্ষেত্রে :)

কেন: কারণ আপনি চান যে আপনার কোডটি সহজেই টেস্টযোগ্য, উপকরযোগ্য ইত্যাদি হয় যাতে আপনি দ্রুত আপনার পরিবর্তনগুলি পরীক্ষা করে এটি বাজারে ঠেলাতে পারেন। আপনি যখন আপনার নিয়ন্ত্রণ রাখবেন এমন কোনও কোডবেসে আপনার যাত্রায় আপনাকে সমর্থন করার জন্য প্রচুর দুর্দান্ত সরঞ্জাম / ফ্রেমওয়ার্ক রয়েছে তখন আপনি কেন তা করবেন না।


ধন্যবাদ উইন্ডারাইডার আমি আর একমত হতে পারি না। মানবজীবন এবং মানবদেহ ডিজাইনের উৎকর্ষতার দুর্দান্ত উদাহরণ.... মেরুদণ্ড একটি ESB এর একটি চমৎকার উদাহরণ:) ...
আনোয়ার হোসেন

15

উদাহরণস্বরূপ, আমাদের 2 শ্রেণি রয়েছে Clientএবং ServiceClientব্যবহ্রতService

public class Service {
    public void doSomeThingInService() {
        // ...
    }
}

নির্ভরতা ইনজেকশন ছাড়াই

উপায় 1)

public class Client {
    public void doSomeThingInClient() {
        Service service = new Service();
        service.doSomeThingInService();
    }
}

উপায় 2)

public class Client {
    Service service = new Service();
    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

উপায় 3)

public class Client {
    Service service;
    public Client() {
        service = new Service();
    }
    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

1) 2) 3) ব্যবহার

Client client = new Client();
client.doSomeThingInService();

সুবিধাদি

  • সহজ

অসুবিধেও

  • পরীক্ষার Clientক্লাসের জন্য শক্ত
  • আমরা যখন পরিবর্তন Serviceকন্সট্রাকটর, আমরা তৈরি সব জায়গায় পরিবর্তন কোডে প্রয়োজন Serviceবস্তুর

নির্ভরতা ইনজেকশন ব্যবহার করুন

ওয়ে 1) কনস্ট্রাক্টর ইনজেকশন

public class Client {
    Service service;

    Client(Service service) {
        this.service = service;
    }

    // Example Client has 2 dependency 
    // Client(Service service, IDatabas database) {
    //    this.service = service;
    //    this.database = database;
    // }

    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

ব্যবহার

Client client = new Client(new Service());
// Client client = new Client(new Service(), new SqliteDatabase());
client.doSomeThingInClient();

ওয়ে 2) সেটার ইনজেকশন

public class Client {
    Service service;

    public void setService(Service service) {
        this.service = service;
    }

    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

ব্যবহার

Client client = new Client();
client.setService(new Service());
client.doSomeThingInClient();

উপায় 3) ইন্টারফেস ইনজেকশন

পরীক্ষা করে দেখুন https://en.wikipedia.org/wiki/Dependency_injection

===

এখন, এই কোডটি ইতিমধ্যে অনুসরণ করা হয়েছে Dependency Injectionএবং এটি পরীক্ষার Clientশ্রেণীর পক্ষে সহজ ।
তবে, আমরা এখনও new Service()অনেক সময় ব্যবহার করি এবং Serviceকনস্ট্রাক্টর পরিবর্তন করার সময় এটি ভাল হয় না । এটি প্রতিরোধ করতে আমরা ডিআই ইনজেক্টর ব্যবহার করতে পারি
1) সাধারণ ম্যানুয়ালInjector

public class Injector {
    public static Service provideService(){
        return new Service();
    }

    public static IDatabase provideDatatBase(){
        return new SqliteDatabase();
    }
    public static ObjectA provideObjectA(){
        return new ObjectA(provideService(...));
    }
}

ব্যবহার

Service service = Injector.provideService();

2) লাইব্রেরিটি ব্যবহার করুন: অ্যান্ড্রয়েড ডাগার 2 এর জন্য

সুবিধাদি

  • পরীক্ষা সহজ করুন
  • আপনি যখন পরিবর্তন করেন Service, আপনাকে কেবল ইনজেক্টর শ্রেণিতে এটি পরিবর্তন করতে হবে
  • আপনি যদি ব্যবহারটি ব্যবহার করেন Constructor Injection, আপনি যখন কনস্ট্রাক্টরের দিকে তাকান Client, আপনি দেখবেন Clientশ্রেণীর কত নির্ভরতা

অসুবিধেও

  • আপনি যদি ব্যবহারটি ব্যবহার Constructor Injectionকরেন Serviceতবে তৈরি করার সময় অবজেক্টটি Clientতৈরি হয়, কিছু সময় আমরা Clientক্লাসে ফাংশনটি ব্যবহার Serviceনা করে তৈরি করি যাতে Serviceঅপচয় হয়

নির্ভরতা ইনজেকশন সংজ্ঞা

https://en.wikipedia.org/wiki/Dependency_injection

নির্ভরতা হ'ল এমন একটি বস্তু যা ব্যবহার করা যায় ( Service)
একটি ইনজেকশন হ'ল নির্ভরতা ( Service) এর উপর নির্ভরশীল অবজেক্ট ( Client) ব্যবহার করা হয় যা এটি ব্যবহার করবে


13

এর অর্থ হ'ল বস্তুগুলির কেবলমাত্র তার কাজ করার জন্য প্রয়োজনীয় যতগুলি নির্ভরতা থাকা উচিত এবং নির্ভরতা কম হওয়া উচিত। তদ্ব্যতীত, কোনও বস্তুর নির্ভরতা ইন্টারফেসের উপর হওয়া উচিত এবং যখন সম্ভব হয় তখন "কংক্রিট" অবজেক্টের উপর নয়। (একটি কংক্রিট অবজেক্টটি নতুন কীওয়ার্ড দিয়ে তৈরি যে কোনও বস্তু)) আলগা কাপলিং বৃহত্তর পুনরায় ব্যবহারযোগ্যতা, সহজ রক্ষণাবেক্ষণের প্রচার করে এবং ব্যয়বহুল পরিষেবাদির জায়গায় আপনাকে সহজেই "উপহাস" অবজেক্ট সরবরাহ করতে দেয়।

"ডিপেন্ডেন্সি ইনজেকশন" (ডিআই) "ইনভার্শন অফ কন্ট্রোল" (আইওসি) নামেও পরিচিত, এই শিথিল যুগলকে উত্সাহ দেওয়ার কৌশল হিসাবে ব্যবহার করা যেতে পারে।

ডিআই বাস্তবায়নের জন্য দুটি প্রাথমিক পন্থা রয়েছে:

  1. কনস্ট্রাক্টর ইনজেকশন
  2. সেটার ইনজেকশন

কনস্ট্রাক্টর ইনজেকশন

এটি এর নির্মাণকারীর অবজেক্টের নির্ভরতা পাস করার কৌশল।

নোট করুন কনস্ট্রাক্টর একটি ইন্টারফেস গ্রহণ করে এবং কংক্রিট অবজেক্টকে নয়। এছাড়াও, নোট করুন যদি অর্ডারডাও প্যারামিটারটি শূন্য থাকে তবে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হয়। এটি বৈধ নির্ভরতা প্রাপ্তির গুরুত্বকে জোর দেয়। কনস্ট্রাক্টর ইনজেকশন, আমার মতে, কোনও বস্তুকে এর নির্ভরতা দেওয়ার জন্য পছন্দের প্রক্রিয়া। এটি সঠিকভাবে কার্যকর করার জন্য "ব্যক্তি" অবজেক্টটিতে কোন নির্ভরতা দেওয়া দরকার সেই অবজেক্টটি চালনার সময় এটি বিকাশকারীদের কাছে স্পষ্ট।

সেটার ইনজেকশন

তবে নীচের উদাহরণটি বিবেচনা করুন ... ধরুন আপনার দশটি পদ্ধতি রয়েছে যার কোনও নির্ভরতা নেই এমন একটি শ্রেণি রয়েছে তবে আপনি একটি নতুন পদ্ধতি যুক্ত করছেন যা আইডিএওর উপর নির্ভরশীলতা রাখে না। আপনি কনস্ট্রাক্টর ইনজেকশন ব্যবহার করতে কনস্ট্রাক্টরকে পরিবর্তন করতে পারেন, তবে এটি আপনাকে সমস্ত জায়গাতে সমস্ত কনস্ট্রাক্টর কলগুলিতে পরিবর্তন করতে বাধ্য করতে পারে। বিকল্পভাবে, আপনি কেবল নতুন কনস্ট্রাক্টর যুক্ত করতে পারেন যা নির্ভরতা নেয় তবে আপনি কীভাবে কোনও বিকাশকারী সহজেই জানেন যে কখন একজন নির্মাণকারীকে অন্যটির উপর ব্যবহার করতে হয়। অবশেষে, যদি নির্ভরতা তৈরি করা খুব ব্যয়বহুল হয় তবে কেন এটি তৈরি করা হবে এবং নির্মাণকারীর কাছে দেওয়া হবে যখন এটি কেবল বিরলভাবেই ব্যবহৃত হতে পারে? "সেটার ইনজেকশন" হ'ল আরও একটি ডিআই কৌশল যা এই জাতীয় পরিস্থিতিতে ব্যবহার করা যেতে পারে।

সেটার ইনজেকশন কনস্ট্রাক্টরের উপর নির্ভরতা জোর করে না। পরিবর্তে, নির্ভরতার প্রয়োজনবস্তু দ্বারা প্রকাশিত জনসাধারণের সম্পত্তিগুলিতে সেট করা থাকে। পূর্বে সূচিত হিসাবে, এটি করার জন্য প্রাথমিক প্রেরণাগুলি অন্তর্ভুক্ত:

  1. কোনও উত্তরাধিকার শ্রেণীর নির্মাতা পরিবর্তন না করে নির্ভরতা ইনজেকশন সমর্থন Support
  2. ব্যয়বহুল সংস্থান বা পরিষেবাগুলি যতটা সম্ভব দেরীতে তৈরি করার অনুমতি দেওয়া হয় এবং কেবল যখন প্রয়োজন হয়।

উপরের কোডটি কেমন দেখাচ্ছে তার উদাহরণ এখানে:

public class Person {
    public Person() {}

    public IDAO Address {
        set { addressdao = value; }
        get {
            if (addressdao == null)
              throw new MemberAccessException("addressdao" +
                             " has not been initialized");
            return addressdao;
        }
    }

    public Address GetAddress() {
       // ... code that uses the addressdao object
       // to fetch address details from the datasource ...
    }

    // Should not be called directly;
    // use the public property instead
    private IDAO addressdao;

3
আমি মনে করি আপনার প্রথম অনুচ্ছেদটি প্রশ্ন থেকে দূরে রয়েছে, এবং এটি ডিআই এর কোনও সংজ্ঞা নয় (অর্থাত্, আপনি সোলিড সংজ্ঞা দেওয়ার চেষ্টা করছেন, ডিআই নয়)। প্রযুক্তিগতভাবে, আপনার 100 নির্ভরতা থাকলেও আপনি এখনও নির্ভরতা ইনজেকশন ব্যবহার করতে পারেন। একইভাবে, কংক্রিট নির্ভরতা ইনজেকশন করা সম্ভব - এটি এখনও নির্ভরতা ইনজেকশন।
জে সুলিভান

10

আমি মনে করি যেহেতু সবাই ডিআই-র পক্ষে লিখেছেন, তাই আমাকে কয়েকটি প্রশ্ন জিজ্ঞাসা করুন ..

  1. আপনার যখন ডিআই-এর একটি কনফিগারেশন রয়েছে যেখানে সমস্ত প্রকৃত বাস্তবায়ন (ইন্টারফেস নয়) যা ক্লাসে ইনজেকশনের জন্য চলেছে (উদাহরণস্বরূপ একটি নিয়ন্ত্রণকারীর পরিষেবা) কেন তা কোনও ধরণের হার্ড-কোডিং নয়?
  2. আমি যদি রানটাইমে অবজেক্টটি পরিবর্তন করতে চাই? উদাহরণস্বরূপ, আমার কনফিগারেশনটি ইতিমধ্যে বলেছে যখন আমি মাইকন্ট্রোলার ইনস্ট্যান্ট করি, ফাইললগারকে আইলোগার হিসাবে ইনজেক্ট করি। তবে আমি ডাটাবেস লগার ইনজেকশন করতে চাই।
  3. যখনই আমি আমার AClass এর কী কী জিনিসগুলির প্রয়োজন তা পরিবর্তন করতে চাই, আমাকে এখন দুটি জায়গার সন্ধান করতে হবে - বর্গ নিজেই এবং কনফিগারেশন ফাইল। এটি কীভাবে জীবনকে সহজ করে তোলে?
  4. যদি AClass এর এপ্রোপার্টিটি ইনজেকশন না দেওয়া হয়, তবে এটির উপহাস করা কি আরও শক্ত?
  5. প্রথম প্রশ্নে ফিরে যাচ্ছি। যদি নতুন অবজেক্ট () ব্যবহার করা খারাপ হয় তবে আমরা কীভাবে প্রয়োগটি প্রয়োগ করব এবং ইন্টারফেসটি নয়? আমি মনে করি আপনারা অনেকে বলছেন আমরা আসলে ইন্টারফেসটি ইনজেকশন দিচ্ছি তবে কনফিগারেশন আপনাকে সেই ইন্টারফেসের প্রয়োগটি নির্দিষ্ট করে দেয় .. রানটাইম সময় নয় .. এটি সংকলনের সময় হার্ডকোডযুক্ত।

এটি @ অ্যাডাম এন পোস্ট করা উত্তরের ভিত্তিতে তৈরি।

পার্সন সার্ভিসেসকে আর আর গ্রুপমেম্বারশীপ সার্ভিস নিয়ে চিন্তা করতে হবে না? আপনি স্রেফ উল্লেখ করেছেন গ্রুপ মেম্বারশিপের একাধিক জিনিস (বস্তু / বৈশিষ্ট্য) এটি নির্ভর করে। জিএমএস সার্ভিস যদি পিএস সার্ভিসে প্রয়োজন হয় তবে আপনি এটি সম্পত্তি হিসাবে পেয়ে যাবেন। আপনি এটি ইনজেকশন দিয়েছেন কিনা তা নির্বিশেষে আপনি এটি উপহাস করতে পারেন। আমি কেবলমাত্র একবার এটি ইনজেকশন করতে চাইছি যদি জিএমএস সার্ভিসে আরও নির্দিষ্ট শিশু ক্লাস থাকে, যা আপনি রানটাইম পর্যন্ত জানেন না। তারপরে আপনি সাবক্লাসটি ইনজেকশন করতে চান। অথবা আপনি যদি এটি সিঙ্গলটন বা প্রোটোটাইপ হিসাবে ব্যবহার করতে চান। সত্য কথা বলতে গেলে, কনফিগারেশন ফাইলটিতে সমস্ত কিছু হার্ডকোডযুক্ত রয়েছে যতক্ষণ না কোনও সংকলনের সময় এটি কোন ধরণের (ইন্টারফেস) ইনজেক্ট করতে চলেছে sub

সম্পাদনা

ডিআই-তে জোস মারিয়া অ্যারানজের একটি দুর্দান্ত মন্তব্য

নির্ভরতার দিক নির্ধারণ করতে এবং যে কোনও আঠালো কোড লেখার জন্য ডিআই কোনও প্রয়োজন মুছে ফেলে সংহতি বাড়ায়।

মিথ্যা। নির্ভরতার দিকনির্দেশটি এক্সএমএল আকারে বা টিকা হিসাবে রয়েছে, আপনার নির্ভরতাগুলি এক্সএমএল কোড এবং টীকা হিসাবে লেখা হয় are এক্সএমএল এবং টীকাগুলি হ'ল উত্স কোড।

ডিআই আপনার সমস্ত উপাদানগুলিকে মডুলার করে (অর্থাত্ পুনঃসারণযোগ্য) তৈরি করে এবং একে অপরের সাথে সংজ্ঞাযুক্ত ইন্টারফেসগুলি কমিয়ে দেয় reduces

মিথ্যা। ইন্টারফেসের উপর ভিত্তি করে একটি মডিউল কোড তৈরি করতে আপনার কোনও ডিআই ফ্রেমওয়ার্কের দরকার নেই।

প্রতিস্থাপনযোগ্য সম্পর্কে: খুব সাধারণ .প্রাপ্তি সংরক্ষণাগার এবং ক্লাস.ফর্মের নাম সহ আপনি যে ক্লাস পরিবর্তন করতে পারবেন তা সংজ্ঞায়িত করতে পারেন। যদি আপনার কোডের কোনও শ্রেণি পরিবর্তন করা যায় তবে জাভা আপনার জন্য নয়, একটি স্ক্রিপ্টিং ভাষা ব্যবহার করুন। উপায় দ্বারা: টীকাগুলি পুনরায় সংশোধন না করে পরিবর্তন করা যায় না।

আমার মতে ডিআই ফ্রেমওয়ার্কগুলির একমাত্র কারণ: বয়লার প্লেট হ্রাস। ভালভাবে সম্পন্ন ফ্যাক্টরি সিস্টেমের সাহায্যে আপনি একই পছন্দটি করতে পারেন, আপনার পছন্দের ডিআই ফ্রেমওয়ার্ক হিসাবে আরও নিয়ন্ত্রিত এবং আরও অনুমানযোগ্য, ডিআই ফ্রেমওয়ার্কগুলি কোড কমানোর প্রতিশ্রুতি দেয় (এক্সএমএল এবং টীকাগুলিও উত্স কোড)। সমস্যাটি হ'ল এই বয়লার প্লেট হ্রাস খুব খুব সাধারণ ক্ষেত্রে (এক ক্লাসে প্রতি উদাহরণ এবং অনুরূপ) সত্যই সত্য, কখনও কখনও আসল বিশ্বে বরাদ্দকৃত পরিষেবার বস্তুটি বাছাই করা কোনও একক বস্তুতে কোনও শ্রেণি ম্যাপিংয়ের মতো সহজ নয়।


8

জনপ্রিয় উত্তরগুলি অপ্রয়োজনীয়, কারণ তারা নির্ভরতা ইঞ্জেকশনটিকে এমনভাবে সংজ্ঞায়িত করে যে দরকারী নয়। আসুন আমরা সম্মত হই যে "নির্ভরতা" দ্বারা আমরা কিছু পূর্ব-বিদ্যমান অন্যান্য অবজেক্টকে বোঝাতে চাই যা আমাদের এক্স এক্সের প্রয়োজন। তবে আমরা যখন বলি না তখন আমরা "নির্ভরতা ইনজেকশন" করছি

$foo = Foo->new($bar);

আমরা কেবল কনস্ট্রাক্টরের মধ্যে যে পাসিং পরামিতি কল। কনস্ট্রাক্টরদের আবিষ্কার হওয়ার পর থেকেই আমরা এটি নিয়মিত করে আসছি।

"ডিপেন্ডেন্সি ইনজেকশন" কে একধরণের "নিয়ন্ত্রণের বিপরীতমুখী" হিসাবে বিবেচনা করা হয়, যার অর্থ কিছুটা যুক্তি কলকের বাইরে নেওয়া হয়। কলার যখন পরামিতিগুলিতে যায় তখন কেস হয় না, তাই যদি এটি ডিআই হয়, ডিআই নিয়ন্ত্রণের বিপরীতিকে বোঝায় না।

ডিআই এর অর্থ কলার এবং কনস্ট্রাক্টরের মধ্যে একটি মধ্যবর্তী স্তর রয়েছে যা নির্ভরতা পরিচালনা করে। একটি মেকফিল নির্ভরতা ইনজেকশনের একটি সাধারণ উদাহরণ। "কলার" হ'ল ব্যক্তি কমান্ড লাইনে "মেক বার" টাইপ করে এবং "কনস্ট্রাক্টর" সংকলক হয়। Makefile নির্দিষ্ট করে যে বার foo এর উপর নির্ভর করে এবং এটি একটি করে

gcc -c foo.cpp; gcc -c bar.cpp

করার আগে

gcc foo.o bar.o -o bar

"মেক বার" টাইপকারী ব্যক্তির জানা দরকার নেই যে বারটি ফু এর উপর নির্ভর করে। "মেক বার" এবং জিসিসির মধ্যে নির্ভরতা ইনজেকশন করা হয়েছিল।

মধ্যবর্তী স্তরের মূল উদ্দেশ্যটি কেবল নির্মাণকারীর উপর নির্ভরতাগুলিতে প্রবেশ করা নয়, সমস্ত নির্ভরতা কেবল একটি জায়গায় তালিকাভুক্ত করা এবং কোডার থেকে তাদের আড়াল করা (কোডার তাদের সরবরাহ না করা)।

সাধারণত মধ্যবর্তী স্তরটি নির্মাণকৃত অবজেক্টগুলির জন্য কারখানাগুলি সরবরাহ করে, যা প্রতিটি অনুরোধ করা অবজেক্টের ধরণের সন্তুষ্ট হতে হবে এমন একটি ভূমিকা প্রদান করতে হবে। এটি কারণ হিসাবে একটি মধ্যবর্তী স্তর যা নির্মাণের বিবরণগুলি গোপন করে আপনি ইতিমধ্যে কারখানার দ্বারা আরোপিত বিমূর্ততা জরিমানা ব্যয় করেছেন, যাতে আপনি কারখানাগুলিও ব্যবহার করতে পারেন।


8

ডিপেন্ডেন্সি ইনজেকশন মানে কোডের একটি অংশের (যেমন কোনও শ্রেণীর) বোঝার উপায় (যেমন কোনও শ্রেণি) কোনও হার্ডকোড ছাড়াই একটি মডুলার উপায়ে (কোডের অন্যান্য অংশগুলি, যেমন অন্যান্য ক্লাস, এটি নির্ভর করে) to এগুলি অবাধে পরিবর্তিত বা ওভাররাইড করা যেতে পারে, বা এমনকি অন্য সময়ে লোড করাও যেতে পারে, প্রয়োজন অনুসারে)

(এবং পিএস, হ্যাঁ এটি একটি অতি-হাইপ্রেড 25 $ একটি বরং সাধারণ, ধারণার নাম হয়ে গেছে) , আমার .25সেন্টগুলি


8

আমি জানি ইতিমধ্যে অনেক উত্তর আছে তবে আমি এটি খুব সহায়ক বলে মনে করেছি: http://tutorials.jenkov.com/d dependency- inication/ index.html

নির্ভরতা নেই:

public class MyDao {

  protected DataSource dataSource = new DataSourceImpl(
    "driver", "url", "user", "password");

  //data access methods...
  public Person readPerson(int primaryKey) {...}     
}

নির্ভরতা:

public class MyDao {

  protected DataSource dataSource = null;

  public MyDao(String driver, String url, String user, String password) {
    this.dataSource = new DataSourceImpl(driver, url, user, password);
  }

  //data access methods...
  public Person readPerson(int primaryKey) {...}
}

লক্ষ্য করুন কীভাবে DataSourceImplইনস্ট্যান্টেশনটি কনস্ট্রাক্টরে সরানো হয়েছে। কনস্ট্রাক্টর চারটি পরামিতি নেয় যা দ্বারা প্রয়োজনীয় চারটি মান DataSourceImpl। যদিও MyDaoশ্রেণি এখনও এই চারটি মানের উপর নির্ভর করে, এটি আর এই নির্ভরতাগুলি নিজেই সন্তুষ্ট করে না। এগুলি MyDaoযেমন শ্রেণীর উদাহরণ তৈরি করে তা সরবরাহ করা হয় ।


1
আপনার ডিআইসোর্সআইম্প ইতিমধ্যে নির্মিত ইন্টারফেসের মাধ্যমে ডিআই আপনাকে পাস করবে না?
PmanAce

6

নির্ভরতা ইনজেকশন হ'ল সাধারণত "নির্ভরতা অবলম্বন" প্রয়োজনীয়তা হিসাবে অভিহিত করা যেতে পারে এর একটি সম্ভাব্য সমাধান। নির্ভরতা অবলম্বন হ'ল একটি ক্লাসের জন্য নির্ভরশীলতা সরবরাহের প্রক্রিয়া থেকে 'সুস্পষ্ট' প্রকৃতির বাইরে নিয়ে যাওয়ার একটি পদ্ধতি যা এর প্রয়োজন হয় এবং অতএব, কোনওভাবে বলা হয় যে শ্রেণীর উপর নির্ভরশীলতার বিধান রয়েছে। এই অগত্যা একটি খারাপ জিনিস নয়। প্রকৃতপক্ষে, কোনও শ্রেণীর উপর নির্ভরতা যেভাবে সরবরাহ করা হয় তা অবিশ্বাস করে ক্লাসের বাইরের কিছু নির্ভরতা তৈরির জন্য দায়বদ্ধ যার অর্থ, বিভিন্ন পরিস্থিতিতে, কোনও পরিবর্তন না করেই নির্ভরতার একটি আলাদা বাস্তবায়ন শ্রেণীর সরবরাহ করা যেতে পারে ক্লাসে উত্পাদন এবং পরীক্ষার মোডগুলির মধ্যে স্যুইচ করার জন্য এটি দুর্দান্ত (উদাহরণস্বরূপ, 'মক' পরিষেবা নির্ভরতা ব্যবহার করে)।

দুর্ভাগ্যক্রমে খারাপ অংশটি কিছু লোকেরা ধরে নিয়েছে যে নির্ভরতা অবলম্বন করার জন্য আপনার একটি বিশেষ কাঠামো প্রয়োজন এবং যদি আপনি কোনও নির্দিষ্ট কাঠামো এটির জন্য না বেছে নেন তবে আপনি কোনওরকম একজন 'কম' প্রোগ্রামার হন। আরেকটি, চরম বিরক্তিকর মিথ, অনেকের বিশ্বাস, হ'ল নির্ভরতা ইনজেকশন হ'ল নির্ভরতা অবলম্বন করার একমাত্র উপায়। এটি প্রদর্শিতভাবে এবং icallyতিহাসিকভাবে এবং স্পষ্টতই 100% ভুল তবে আপনার কিছু লোককে বোঝাতে সমস্যা হবে যে আপনার নির্ভরতা অবলম্বনের প্রয়োজনীয়তার জন্য নির্ভরতা ইনজেকশনের বিকল্প রয়েছে।

প্রোগ্রামাররা বছরের পর বছর ধরে নির্ভরতা অবলম্বনের প্রয়োজনীয়তা বুঝতে পেরেছিল এবং নির্ভরতা ইঞ্জেকশনটি ধারণার আগে এবং পরে উভয়ই অনেক বিকল্প সমাধান বিকশিত হয়েছিল। সেখানে কারখানার নিদর্শন আছে, কিন্তু আরো অনেক অপশন ThreadLocal ব্যবহার যেখানে একটি নির্দিষ্ট উদাহরণস্বরূপ কোন ইনজেকশন প্রয়োজন হয় হয় - এতে নির্ভরতা কার্যকরভাবে থ্রেড যা (সুবিধার স্ট্যাটিক সংগ্রহকারী পদ্ধতির মাধ্যমে) বস্তু উপলব্ধ সুবিধা রয়েছে মধ্যে ইনজেকশনের হয় কোনোযে শ্রেণীর জন্য এটি প্রয়োজনীয় ক্লাসগুলিতে টীকা যুক্ত না করে এটি প্রয়োজন এবং এটি ঘটানোর জন্য জটিল XML 'আঠালো' সেট আপ করুন। আপনার নির্ভরতা যখন অধ্যবসায়ের জন্য প্রয়োজন হয় (জেপিএ / জেডিও বা যাই হোক না কেন) এটি আপনাকে 'স্বচ্ছ পীড়াপীড়ন' অর্জন করতে দেয় খুব সহজ এবং ডোমেন মডেল এবং ব্যবসায়িক মডেল ক্লাসগুলি নিখুঁতভাবে POJOs দিয়ে গঠিত (যেমন কোনও ফ্রেমওয়ার্ক নির্দিষ্ট / টীকাগুলিতে আবদ্ধ নয়)।


5

বইটি থেকে, ' ওয়েল-গ্রাউন্ডেড জাভা ডেভেলপার: জাভা 7 এর গুরুত্বপূর্ণ কৌশল এবং বহুগ্লাট প্রোগ্রামিং

ডিআই আইওসি-র একটি বিশেষ ফর্ম, যার মাধ্যমে আপনার নির্ভরতাগুলি খুঁজে পাওয়ার প্রক্রিয়াটি আপনার বর্তমানে সম্পাদনকারী কোডের প্রত্যক্ষ নিয়ন্ত্রণের বাইরে outside


5

প্রযুক্তিগত বিবরণে যাওয়ার আগে প্রথমে এটি বাস্তব জীবনের উদাহরণ দিয়ে কল্পনা করুন কারণ নির্ভরতা ইঞ্জেকশন শিখতে আপনি অনেক প্রযুক্তিগত জিনিস পাবেন তবে আমার মতো সর্বাধিক সময় লোকেরা এর মূল ধারণাটি পেতে পারেন না।

প্রথম ছবিতে, ধরে নিন যে আপনার কাছে প্রচুর itesক্যবদ্ধ গাড়ি কারখানা রয়েছে। একটি গাড়ি আসলে অ্যাসেম্বলি ইউনিটে নির্মিত তবে এর ইঞ্জিন , আসনগুলির পাশাপাশি চাকাগুলির প্রয়োজন । সুতরাং সমাবেশ ইউনিট এই সমস্ত ইউনিটের উপর নির্ভরশীল এবং এগুলি কারখানার নির্ভরতা

আপনি অনুভব করতে পারেন যে এখন এই কারখানার সমস্ত কাজ বজায় রাখা খুব জটিল কারণ মূল টাস্কের পাশাপাশি (এসেম্বলি ইউনিটে গাড়ি সমাবেশ করা) আপনাকে অন্যান্য ইউনিটগুলিতেও ফোকাস করতে হবে । এটি রক্ষণাবেক্ষণ করা এখন খুব ব্যয়বহুল এবং কারখানার বিল্ডিং বিশাল তাই এটি আপনার অতিরিক্ত টাকা ভাড়া নেওয়ার জন্য নেয়।

এখন, দ্বিতীয় ছবি দেখুন। যদি আপনি এমন কিছু সরবরাহকারী সংস্থাগুলি খুঁজে পান যা আপনাকে নিজের স্ব-উত্পাদন ব্যয়ের চেয়ে চাকা , আসন এবং ইঞ্জিন কম দামে সরবরাহ করে তবে এখন এগুলি আপনার কারখানায় তৈরি করার দরকার নেই। আপনি কেবলমাত্র আপনার সংসদীয় ইউনিটের জন্য একটি ছোট বিল্ডিং ভাড়া নিতে পারেন যা আপনার রক্ষণাবেক্ষণের কাজটি কমিয়ে দেবে এবং আপনার অতিরিক্ত ভাড়া ব্যয় হ্রাস করবে। এখন আপনি কেবলমাত্র আপনার মূল কার্য (কার অ্যাসেমব্লি) উপর দৃষ্টি নিবদ্ধ করতে পারেন।

এখন আমরা বলতে পারি সব নির্ভরতা একটি গাড়ির একত্রিতকরনের জন্য হয় ইনজেকশনের থেকে কারখানা উপর প্রদানকারীর । এটি বাস্তব জীবনের নির্ভরতা ইনজেকশন (ডিআই) এর একটি উদাহরণ ।

প্রযুক্তিগত কথায় এখন নির্ভরতা ইনজেকশন এমন একটি কৌশল যা একটি বস্তু (বা স্থির পদ্ধতি) অন্য কোনও বস্তুর নির্ভরতা সরবরাহ করে। সুতরাং, অন্য কারও কাছে অবজেক্ট তৈরির কাজটি সরাসরি স্থানান্তর করে সরাসরি নির্ভরতা ব্যবহার করে তাকে নির্ভরতা ইনজেকশন বলে।

এটি আপনাকে এখন কিছু প্রযুক্তিগত শব্দ দিয়ে ডিআই শিখতে সহায়তা করবে। এটি কখন ডিআই ব্যবহার করবে এবং কখন ব্যবহার করা উচিত নয় তা দেখায় ।

সব এক কারখানায়

সরল গাড়ির কারখানা


1
40 ইশ এর মধ্যে পরিষ্কার উত্তর। বাস্তব জীবনের উদাহরণ এবং চিত্র। +1 টি। গ্রহণযোগ্য উত্তর হওয়া উচিত।
মার্চে রেমি

4

বই অ্যাপ্রেস.স্প্রিং.পার্সিস্টি.বিহ.হাইবারনেট.অ্যাক্ট .2010 থেকে

নির্ভরতা ইনজেকশনটির উদ্দেশ্য হ'ল আপনার অ্যাপ্লিকেশন ব্যবসার যুক্তি থেকে বাহ্যিক সফ্টওয়্যার উপাদানগুলি সমাধান করার কাজটি দ্বিগুণ করা depend নির্ভরতা ইনজেকশন ছাড়াই, কোনও উপাদান কীভাবে প্রয়োজনীয় পরিষেবাগুলি অ্যাক্সেস করে তার বিশদটি উপাদানটির কোডের সাথে মিশে যেতে পারে। এটি কেবল ত্রুটির সম্ভাবনা বৃদ্ধি করে না, কোড ফোলা যোগ করে এবং রক্ষণাবেক্ষণের জটিলতাগুলিকে বাড়িয়ে তোলে; এটি আরও ঘনিষ্ঠভাবে উপাদানগুলিকে একত্রে যুক্ত করে, রিফ্যাক্টরিং বা পরীক্ষার সময় নির্ভরতাগুলি সংশোধন করা কঠিন করে তোলে।


4

ডিপেন্ডেন্সি ইনজেকশন (ডিআই) ডিজাইন প্যাটার্নগুলির মধ্যে একটি, যা ওওপির প্রাথমিক বৈশিষ্ট্যটি ব্যবহার করে - অন্য একটি বস্তুর সাথে এক বস্তুর সম্পর্ক। উত্তরাধিকার একটি বস্তুকে আরও জটিল এবং সুনির্দিষ্ট আরেকটি বস্তু করার জন্য উত্তরাধিকার সূত্রে প্রাপ্ত হয়, তবে সম্পর্ক বা সংযোগটি কেবলমাত্র অ্যাট্রিবিউট ব্যবহার করে একটি বস্তু থেকে অন্য বস্তুর জন্য পয়েন্টার তৈরি করে। ইন্টারফেস এবং লুকানো কোড যেমন ডিআই এর শক্তি ওওপির অন্যান্য বৈশিষ্ট্যের সাথে একত্রে হয়। মনে করুন, লাইব্রেরিতে আমাদের গ্রাহক (গ্রাহক) রয়েছে, যা সরলতার জন্য কেবল একটি বই ধার করতে পারে।

বইয়ের ইন্টারফেস:

package com.deepam.hidden;

public interface BookInterface {

public BookInterface setHeight(int height);
public BookInterface setPages(int pages);   
public int getHeight();
public int getPages();  

public String toString();
}

এরপরে আমাদের অনেক ধরণের বই থাকতে পারে; টাইপগুলির মধ্যে একটি হ'ল কল্পকাহিনী:

package com.deepam.hidden;

public class FictionBook implements BookInterface {
int height = 0; // height in cm
int pages = 0; // number of pages

/** constructor */
public FictionBook() {
    // TODO Auto-generated constructor stub
}

@Override
public FictionBook setHeight(int height) {
  this.height = height;
  return this;
}

@Override
public FictionBook setPages(int pages) {
  this.pages = pages;
  return this;      
}

@Override
public int getHeight() {
    // TODO Auto-generated method stub
    return height;
}

@Override
public int getPages() {
    // TODO Auto-generated method stub
    return pages;
}

@Override
public String toString(){
    return ("height: " + height + ", " + "pages: " + pages);
}
}

গ্রাহকরা এখন বইয়ের সাথে সংযুক্ত থাকতে পারেন:

package com.deepam.hidden;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Subscriber {
BookInterface book;

/** constructor*/
public Subscriber() {
    // TODO Auto-generated constructor stub
}

// injection I
public void setBook(BookInterface book) {
    this.book = book;
}

// injection II
public BookInterface setBook(String bookName) {
    try {
        Class<?> cl = Class.forName(bookName);
        Constructor<?> constructor = cl.getConstructor(); // use it for parameters in constructor
        BookInterface book = (BookInterface) constructor.newInstance();
        //book = (BookInterface) Class.forName(bookName).newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    return book;
}

public BookInterface getBook() {
  return book;
}

public static void main(String[] args) {

}

}

তিনটি শ্রেণি এটির নিজস্ব বাস্তবায়নের জন্য লুকিয়ে থাকতে পারে। এখন আমরা ডিআই-র জন্য এই কোডটি ব্যবহার করতে পারি:

package com.deepam.implement;

import com.deepam.hidden.Subscriber;
import com.deepam.hidden.FictionBook;

public class CallHiddenImplBook {

public CallHiddenImplBook() {
    // TODO Auto-generated constructor stub
}

public void doIt() {
    Subscriber ab = new Subscriber();

    // injection I
    FictionBook bookI = new FictionBook();
    bookI.setHeight(30); // cm
    bookI.setPages(250);
    ab.setBook(bookI); // inject
    System.out.println("injection I " + ab.getBook().toString());

    // injection II
    FictionBook bookII = ((FictionBook) ab.setBook("com.deepam.hidden.FictionBook")).setHeight(5).setPages(108); // inject and set
    System.out.println("injection II " + ab.getBook().toString());      
}

public static void main(String[] args) {
    CallHiddenImplBook kh = new CallHiddenImplBook();
    kh.doIt();
}
}

নির্ভরতা ইনজেকশন কীভাবে ব্যবহার করবেন তা বিভিন্ন উপায়। এটি একক ইত্যাদির সাথে একত্রিত করা সম্ভব, তবে এখনও প্রাথমিকভাবে এটি অন্য কোনও বস্তুর অভ্যন্তরে অবজেক্ট টাইপের বৈশিষ্ট্য তৈরি করেই অনুধাবন করা যায়। দরকারীতাটি কেবলমাত্র এবং কেবল বৈশিষ্ট্যেই রয়েছে, সেই কোডটি যা আমাদের বারবার লিখতে হবে আমাদের জন্য সর্বদা প্রস্তুত এবং সম্পন্ন হয়। এই কারণেই ডিআই এত সংলগ্নভাবে ইনভার্শন অফ কন্ট্রোল (আইওসি) এর সাথে আবদ্ধ হয় যার অর্থ, আমাদের প্রোগ্রামটি অন্য চলমান মডিউলটিকে নিয়ন্ত্রণ করে যা আমাদের কোডে শিমের ইনজেকশন দেয়। (প্রতিটি বস্তু, যা ইনজেকশন দেওয়া যায় তা স্বাক্ষরিত হতে পারে বা একটি শিম হিসাবে বিবেচনা করা যেতে পারে)) উদাহরণস্বরূপ বসন্তে এটি অ্যাপ্লিকেশন কনটেক্সট তৈরি এবং আরম্ভের মাধ্যমে করা হয়ধারক, যা আমাদের জন্য এই কাজ করে। আমরা কেবল আমাদের কোডটিতে প্রসঙ্গ তৈরি করি এবং মটরশুটি শুরু করি। সেই মুহুর্তে ইঞ্জেকশনটি স্বয়ংক্রিয়ভাবে হয়ে গেছে।


4

5 বছরের বাচ্চাদের জন্য নির্ভরতা ইনজেকশন।

আপনি যখন যান এবং নিজের জন্য ফ্রিজের বাইরে জিনিসগুলি পান, আপনি সমস্যা তৈরি করতে পারেন। আপনি দরজাটি খোলা রেখে দিতে পারেন, আপনি মমি বা বাবা চান এমন কিছু পেতে পারেন। আপনি এমনকি এমন কিছু সন্ধান করতে পারেন যা আমাদের কাছে নেই বা যা শেষ হয়ে গেছে।

আপনার যা করা উচিত তা হ'ল একটি প্রয়োজন উল্লেখ করে, "আমার কাছে দুপুরের খাবারের সাথে কিছু পান করার দরকার আছে" এবং তারপরে আমরা খেতে বসলে আপনার কাছে কিছু আছে তা নিশ্চিত করব।


1
এটি পরিষ্কারভাবে একটি পিতামাতার উত্তর। ;)
মার্চে রেমি

4

ক্রিস্টোফার নোরিং থেকে, পাবলো ডিলম্যানের বই "শেখার কৌণিক - দ্বিতীয় সংস্করণ" বই:

"আমাদের হিসাবে অ্যাপ্লিকেশনের বড় হয়ে যায় এবং উন্নতির, আমাদের প্রতিটি কোড সত্ত্বা অভ্যন্তরীণভাবে প্রয়োজন হবে অন্যান্য বস্তু দৃষ্টান্ত , যা ভাল হিসাবে পরিচিত হয় নির্ভরতা সফটওয়্যার ইঞ্জিনিয়ারিং জগতে। কর্ম যেমন ক্ষণস্থায়ী নির্ভরতা নির্ভরশীল ক্লায়েন্ট হিসাবে পরিচিত হয় ইনজেকশন , এবং এটিতে ইঞ্জেক্টর নামের একটি অন্য কোড সত্তার অংশীদারিত্বও অন্তর্ভুক্ত রয়েছে The ইনজেক্টর প্রয়োজনীয় ইনস্ট্যান্টিয়েটিং এবং বুটস্ট্র্যাপিংয়ের দায়িত্ব নেবে নির্ভরতাগুলিসুতরাং তারা সফলভাবে ক্লায়েন্টে ইনজেকশনের মুহুর্ত থেকেই ব্যবহারের জন্য প্রস্তুত। এটি অত্যন্ত গুরুত্বপূর্ণ যেহেতু ক্লায়েন্ট কীভাবে তার নিজস্ব নির্ভরতা ইনস্ট্যান্ট করতে পারে সে সম্পর্কে কিছুই জানে না এবং সেগুলি ব্যবহারের জন্য তারা যে ইন্টারফেসটি প্রয়োগ করে তা কেবল সচেতন । "

থেকে: অ্যান্টন মোসিয়েভ বই "টাইপস্ক্রিপ্ট সহ কৌণিক বিকাশ, দ্বিতীয় সংস্করণ।":

"সংক্ষেপে, দ্বি আপনি একটি মধ্যে কোড লিখতে সাহায্য করে ঢিলেঢালাভাবে মিলিত ভাবে এবং আপনার তোলে কোড আরো testable এবং পুনর্ব্যবহারযোগ্য ।"


3

সাধারণ কথায় নির্ভরতা ইনজেকশন (ডিআই) হ'ল বিভিন্ন অবজেক্টের মধ্যে নির্ভরতা বা আঁটসাঁট পোশাক অপসারণ করার উপায়। নির্ভরতা ইনজেকশন প্রতিটি বস্তুর সাথে সম্মিলিত আচরণ দেয়।

ডিআই হ'ল স্প্রিংয়ের আইওসি অধ্যক্ষের বাস্তবায়ন যা বলে যে "আমাদের ডাকবেন না আমরা আপনাকে ডাকব"। নির্ভরতা ইনজেকশন প্রোগ্রামার ব্যবহার করে নতুন কীওয়ার্ড ব্যবহার করে অবজেক্ট তৈরি করার দরকার নেই।

বস্তুগুলি একবার স্প্রিং পাত্রে লোড করা হয় এবং তারপরে getBean (স্ট্রিং বিনন নাম) পদ্ধতিটি ব্যবহার করে স্প্রিং কন্টেইনার থেকে those অবজেক্টগুলি আনার মাধ্যমে আমরা যখনই তাদের প্রয়োজনবোধ করি সেগুলি পুনরায় ব্যবহার করি।


3

নির্ভরতা ইনজেকশন হ'ল স্প্রিং ফ্রেমওয়ার্ক সম্পর্কিত ধারণাটির কেন্দ্রস্থল any যে কোনও প্রকল্পের বসন্তের কাঠামো তৈরি করা একটি গুরুত্বপূর্ণ ভূমিকা পালন করতে পারে এবং এখানে নির্ভরতা ইঞ্জেকশনটি কলসি হিসাবে আসে।

প্রকৃতপক্ষে, ধরুন জাভাতে আপনি ক্লাস এ এবং ক্লাস বি হিসাবে দুটি পৃথক ক্লাস তৈরি করেছেন এবং ক্লাস বিতে যে কোনও ফাংশন যা আপনি ক্লাস এতে ব্যবহার করতে চান তা পাওয়া যায়, সুতরাং সেই সময় নির্ভরতা ইনজেকশন ব্যবহার করা যেতে পারে। যেখানে আপনি অন্য শ্রেণীর এক শ্রেণীর অবজেক্টকে ক্রেট করতে পারেন, একইভাবে আপনি এটি অ্যাক্সেসযোগ্য করার জন্য পুরো ক্লাসটিকে অন্য শ্রেণিতে ইনজেক্ট করতে পারেন। এইভাবে নির্ভরতা কাটিয়ে উঠতে পারে।

ডিপেন্ডেন্সির ইনজেকশনটি দু'বার শ্রেণিতে সহজভাবে চালিত হয় এবং একই সময় তাদের আলাদা করে রাখে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.