আমার কেন নির্ভরতা ইনজেকশন ব্যবহার করা উচিত?


95

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

আমি নিম্নলিখিতগুলি কেন করব?

class Profile {
    public function deactivateProfile(Setting $setting)
    {
        $setting->isActive = false;
    }
}

নীচের পরিবর্তে?

class Profile {
    public function deactivateProfile()
    {
        $setting = new Setting();
        $setting->isActive = false;
    }
}

8
আপনি প্রোফাইলে নিষ্ক্রিয় করার জন্য একটি হার্ড কোডিং নির্ভরতা প্রবর্তন করছেন () যা খারাপ)। আপনার প্রথমটিতে আরও ডিকপলড কোড রয়েছে যা পরিবর্তন এবং পরীক্ষা করা সহজ করে।
আউলিস রোনকাইনেন

3
আপনি কেন প্রথমটি করবেন? আপনি একটি সেটিংয়ে যাচ্ছেন এবং তার মানটিকে উপেক্ষা করে।
ফিল এন ডিব্ল্যাঙ্ক

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

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

2
আপনার কোড নির্ভরতা ইনজেকশন বা বিপরীতের উদাহরণ নয়। এটি প্যারামিটারাইজেশনের উদাহরণ (যা প্রায়শই ডিআই এর চেয়ে অনেক বেশি ভাল)।
jpmc26

উত্তর:


104

সুবিধাটি হ'ল নির্ভরতা ইনজেকশন ছাড়াই আপনার প্রোফাইল ক্লাস

  • কীভাবে একটি সেটিংস অবজেক্ট তৈরি করতে হবে তা জানতে হবে (একক দায়িত্বের নীতি লঙ্ঘন করে)
  • সর্বদা তার সেটিংস অবজেক্টটি একইভাবে তৈরি করে (উভয়ের মধ্যে একটি সংকীর্ণ সংযোগ তৈরি করে)

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

  • সেটিংস অবজেক্ট তৈরি করার যুক্তি অন্য কোথাও
  • বিভিন্ন ধরণের সেটিংস অবজেক্ট ব্যবহার করা সহজ

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


23
This may seem (or even be) irrelevant in this particular caseআমি আসলে এটি অনেক প্রাসঙ্গিক বলে মনে করি। আপনি কীভাবে সেটিংস পাবেন? আমি দেখেছি অনেকগুলি সিস্টেমে একটি হার্ড-কোডেড ডিফল্ট সেটিংসের সেট এবং একটি সার্বজনীন মুখোমুখি কনফিগারেশন থাকবে, সুতরাং আপনার উভয়টি লোড করতে হবে এবং পাবলিক সেটিংসের সাথে কিছু মান মুছে ফেলতে হবে। এমনকি আপনার ডিফল্ট একাধিক উত্সের প্রয়োজন হতে পারে। সম্ভবত আপনি এমনকি ডিস্ক থেকে কিছু পেয়ে যাচ্ছেন, অন্যরা ডিবি থেকে পাচ্ছেন। সুতরাং, এমনকি সেটিংস পাওয়ার জন্য সম্পূর্ণ যুক্তিটি অ-তুচ্ছ হতে পারে - এবং সম্ভবত কিছু গ্রাহক কোডের উচিত নয় বা যত্ন করা উচিত নয়।
VLAZ

আমরা উল্লেখ করতে পারি যে কোনও অ-তুচ্ছ উপাদান যেমন একটি ওয়েব পরিষেবাদির জন্য অবজেক্টের সূচনাটি $setting = new Setting();ভয়ানকভাবে অক্ষম করে তুলবে । ইনজেকশন এবং অবজেক্ট ইনস্ট্যান্টেশন একবার হয় happens
ভাইকিংস্টিভ

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

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

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

64

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

আমি এই প্রথম হাতটি শিখেছি যখন আমাকে ম্যাজেন্টোর পেপাল ইন্টিগ্রেশনে হার্ড-টু-ক্যা-বাগ বাগ ঠিক করার দায়িত্ব দেওয়া হয়েছিল।

পেপাল যখন ব্যর্থ অর্থ প্রদান সম্পর্কে ম্যাগেন্টোকে বলছিল তখন একটি সমস্যা দেখা দেবে: ম্যাজেন্টো ব্যর্থতা সঠিকভাবে নিবন্ধন করবে না।

একটি সম্ভাব্য ফিক্স "ম্যানুয়ালি" পরীক্ষা করা খুব ক্লান্তিকর হবে: আপনার কোনওরকম কোনও "ব্যর্থ" পেপাল বিজ্ঞপ্তি ট্রিগার করতে হবে। আপনাকে একটি ই-চেক জমা দিতে হবে, এটি বাতিল করতে হবে এবং এটির ত্রুটি থেকে বেরিয়ে যাওয়ার জন্য অপেক্ষা করতে হবে। তার মানে একটি এক-চরিত্রের কোড পরিবর্তন পরীক্ষা করতে 3+ দিন!

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

<?php
// This is the dependency we will inject to facilitate our testing
class MockHttpClient extends Varien_Http_Adapter_Curl {
    function read() {
        // Make Magento think that PayPal said "VERIFIED", no matter what they actually said...
        return "HTTP/1.1 200 OK\n\nVERIFIED";
    }
}

// Here, we trick Magento into thinking PayPal actually sent something back.
// Magento will try to verify it against PayPal's API though, and since it's fake data, it'll always fail.
$ipnPayload = array (
  'invoice'        => '100058137',         // Order ID to test against
  'txn_id'         => '04S87540L2309371A', // Test PayPal transaction ID
  'payment_status' => 'Failed'             // New payment status that Magento should ingest
);

// This is what Magento's controller calls during a normal IPN request.
// Instead of letting Magento talk to PayPal, we "inject" our fake HTTP client, which always returns VERIFIED.
Mage::getModel('paypal/ipn')->processIpnRequest($ipnPayload, new MockHttpClient());

আমি নিশ্চিত যে ডিআই প্যাটার্নটিতে প্রচুর অন্যান্য সুবিধাগুলি রয়েছে তবে বর্ধিত পরীক্ষাযোগ্যতা আমার মনের একক বৃহত্তম সুবিধা

আপনি যদি এই সমস্যার সমাধান সম্পর্কে আগ্রহী হন তবে এখানে গিটহাব রেপোটি দেখুন: https://github.com/b بلupdev/BUCorefix_Paypalstatus


4
নির্ভরতা ইনজেকশন হার্ডকোডযুক্ত নির্ভরতা সহ কোডের চেয়ে কোড পরীক্ষা করা সহজ করে তোলে। ব্যবসায়ের যুক্তি থেকে সম্পূর্ণ নির্ভরতা নির্মূল করা আরও ভাল better
পিঁপড়া পি

1
এবং @ অ্যান্টপি যা প্রস্তাব দেয় তা করার একটি প্রধান উপায় হ'ল প্যারামিটারাইজেশন । পৃষ্ঠার টেমপ্লেট (সাধারণত "মডেল" হিসাবে পরিচিত) পূরণ করার জন্য ব্যবহৃত ডাটাবেস থেকে ডাটাবেস থেকে ফিরে আসা ফলাফলগুলিতে রূপান্তর করার যুক্তি এমনকি জেনে রাখা উচিত নয় যে একটি আনয়ন কী ঘটছে; এটি কেবল ইনপুট হিসাবে objects বস্তু পেতে প্রয়োজন।
jpmc26

4
@ jpmc26 সত্যই - আমি কার্যকরী কোর, অপরিহার্য শেল সম্পর্কে বীণা বোধ করি যা এটি আপনার ডোমেনে ডেটা পাস করার জন্য এটির মধ্যে নির্ভরতা ইনজেকশনের পরিবর্তে কেবল অভিনব একটি নাম। ডোমেইন বিশুদ্ধ না থাকলে, কোনো ঠাট্টা সাথে পরীক্ষিত ইউনিট হতে পারে এবং তারপর শুধু একটি শেল যে অধ্যবসায়, মেসেজিং ইত্যাদি ভালো জিনিস আত্তীকরণ জড়িয়ে রাখা হয়েছে
অ্যান্ট পি

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

26

কেন (এমনকি সমস্যাটি কী)?

আমার কেন নির্ভরতা ইনজেকশন ব্যবহার করা উচিত?

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

উদাহরণ হিসাবে, কল্পনা করুন আপনি একটি রেস কার ভিডিও গেম লিখছেন writing আপনি একটি ক্লাস দিয়ে শুরু করেছিলেন Game, যা একটি তৈরি করে RaceTrack, যা ৮ টি তৈরি করে Cars, যা প্রত্যেকে একটি তৈরি করে Motor। এখন যদি আপনি 4 অতিরিক্ত চান Carsএকটি ভিন্ন ত্বরণ সঙ্গে, আপনি পরিবর্তন করতে হবে উল্লেখ যে বর্গ হয়তো ছাড়া, Game

ক্লিনার কোড

এটি কি ক্লিনার আর্কিটেকচার / কোডের জন্য?

হ্যাঁ

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

List<Car> cars = new List<Car>();
for(int i=0; i<8; i++){
    float acceleration = 0.3f;
    float maxSpeed = 200.0f;
    Motor motor = new Motor(acceleration, maxSpeed);
    Car car = new Car(motor);
    cars.Add(car);
}
RaceTrack raceTrack = new RaceTrack(cars);
Game game = new Game(raceTrack);

এই 4 টি আলাদা গাড়ি যুক্ত করা এখন এই লাইনগুলি যুক্ত করে করা যেতে পারে:

for(int i=0; i<4; i++){
    float acceleration = 0.5f;
    float maxSpeed = 100.0f;
    Motor motor = new Motor(acceleration, maxSpeed);
    Car car = new Car(motor);
    cars.Add(car);
}
  • মধ্যে কোন পরিবর্তন RaceTrack, Game, Car, অথবা Motorপ্রয়োজনীয় ছিল - যার মানে আমরা 100% নিশ্চিত যে আমরা কোনো নতুন বাগ সেখানে পরিচয় দিল না কি হতে পারে!
  • বেশ কয়েকটি ফাইলের মধ্যে ঝাঁপ দেওয়ার পরিবর্তে আপনি একই সাথে আপনার স্ক্রিনে সম্পূর্ণ পরিবর্তন দেখতে সক্ষম হবেন। এটি নিজের দায়বদ্ধতা হিসাবে সৃষ্টি / সেটআপ / কনফিগারেশন দেখার ফল - এটি মোটর তৈরি করা কোনও কাজ নয়।

পারফরম্যান্স বিবেচনা

বা এটি সামগ্রিকভাবে কর্মক্ষমতাকে প্রভাবিত করে?

কোন । তবে আপনার সাথে সম্পূর্ণ সৎ হতে, এটি হতে পারে।

তবে, এমনকি সেক্ষেত্রেও এটি এত হাস্যকর পরিমাণ যা আপনার যত্ন নেওয়ার প্রয়োজন নেই need ভবিষ্যতে যদি কোনও মুহুর্তে আপনাকে 5Mhz সিপিইউ এবং 2 এমবি র‌্যামের সমতুল্য একটি তামাগোচির জন্য কোড লিখতে হয়, তবে সম্ভবত আপনাকে এই সম্পর্কে যত্ন নিতে হতে পারে

99.999% * ক্ষেত্রে এটির আরও ভাল পারফরম্যান্স হবে কারণ আপনি বাগ সংশোধন করতে কম সময় ব্যয় করেছেন এবং আপনার সংস্থান-ভারী অ্যালগরিদমগুলি উন্নত করতে আরও বেশি সময় ব্যয় করেছেন।

* সম্পূর্ণরূপে তৈরি সংখ্যা

যোগ করা তথ্য: "হার্ড-কোডড"

কোনও ভুল করবেন না, এটি এখনও খুব "হার্ড-কোডড" - সংখ্যাগুলি সরাসরি কোডে লেখা থাকে। হার্ড-কোডেড না হওয়ার অর্থ কোনও পাঠ্য ফাইলে সেই মানগুলি সংরক্ষণ করা - যেমন JSON ফর্ম্যাটে - এবং তারপরে সেগুলি ফাইল থেকে পড়ার মতো কিছু হবে।

এটি করার জন্য, আপনাকে কোনও ফাইল পড়ার জন্য কোড যুক্ত করতে হবে এবং তারপরে জেএসওনকে পার্সিং করতে হবে। আপনি যদি উদাহরণটি আবার বিবেচনা করেন; নন-ডিআই সংস্করণে, একটি Carবা Motorএখন একটি ফাইল পড়তে হবে। এটি খুব বেশি বোঝার মত শোনায় না।

ডিআই সংস্করণে, আপনি গেমটি সেট আপ করতে কোডটি যুক্ত করবেন।


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

3
আমি আসলে একবার আড়ডিনোতে (16MHz, 2KB) একটি তামাগোচি তৈরি করেছি
জংকুক

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

17

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

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

সুতরাং আপনার প্রশ্নটি "আমার ফাংশনটিতে যুক্তি কেন নেওয়া উচিত?" সমান এবং এর একই উত্তরগুলির অনেকগুলি রয়েছে, যথা: কলকারীকে সিদ্ধান্ত নিতে দেওয়া

এটি অবশ্যই একটি ব্যয়ের সাথে আসে কারণ এখন আপনি কলারকে কিছু সিদ্ধান্ত নিতে বাধ্য করছেন (যদি আপনি যুক্তিটি optionচ্ছিক না করেন) এবং ইন্টারফেসটি কিছুটা জটিল। বিনিময়ে, আপনি নমনীয়তা অর্জন।

সুতরাং: বিশেষত এই বিশেষ Settingধরণের / মানটি ব্যবহার করার কোনও বিশেষ কারণ আছে কি ? কলিং কোডটি কি কোনও ভিন্ন Settingধরণের / মান চাইবে ? (মনে রাখবেন, পরীক্ষাগুলি কোড হয় !)


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

1
"এটি কেবল ফাংশনগুলিতে যুক্তি দিয়ে যাচ্ছে It's এটি মোটেও একটি নিদর্শন" এটি আমি শুনেছি ডিআইয়ের একমাত্র ভাল বা এমনকি বোধগম্য ব্যাখ্যা (ভাল বেশিরভাগ লোকেরা এটি কী তা নিয়ে কথা বলেন না , বরং এটির সুবিধাগুলিও)) এবং তারপরে তারা "নিয়ন্ত্রণের বিপরীকরণ" এবং "আলগা কাপলিং" এর মতো জটিল জার্গন ব্যবহার করেন যা সত্যই সহজ ধারণা যখন এটি বুঝতে আরও প্রশ্ন প্রয়োজন questions
অ্যাডিসন

7

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

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

এখন, কোডটি যদি এর মতো হয়:

class Profile {
    private $settings;

    public function __construct(Settings $settings) {
        $this->settings = $settings;
    }

    public function deactive() {
        $this->settings->isActive = false;
    }
}

তারপরে আমি বলব আপনি নির্ভরতা ইনজেকশন ব্যবহার করছেন। উল্লেখযোগ্য পার্থক্য হ'ল একটি Settingsবস্তু যা কনস্ট্রাক্টর বা কোনও Profileঅবজেক্টকে দেওয়া হয়।

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

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

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

  1. প্রোফাইল কনস্ট্রাক্টরের ভিতরে সেটিংস অবজেক্ট ইনস্ট্যান্ট করুন

  2. কনস্ট্রাক্টারে সেটিংস অবজেক্টটি পাস করুন এবং প্রোফাইলে প্রয়োগ হওয়া পৃথক ক্ষেত্রগুলির অনুলিপি করুন

সত্যি বলতে, সেটিংস অবজেক্টের মধ্যে সেটিংস অবজেক্টটি পাস করার পরে সেটিংস অবজেক্টের deactivateProfileঅভ্যন্তরীণ ক্ষেত্রটি সংশোধন করা কোড গন্ধ। সেটিংস অবজেক্টটি কেবল তার অভ্যন্তরীণ ক্ষেত্রগুলি পরিবর্তন করতে হবে।


5
The example you give is not dependency injection in the classical sense.- কিছু যায় আসে না। ওও লোকদের মস্তিষ্কে জিনিস রয়েছে তবে আপনি এখনও কোনও কিছুর উপর নির্ভরশীলতা হস্তান্তর করছেন
রবার্ট হার্ভে

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

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

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

7

আমি জানি আমি এই পার্টিতে দেরি করে আসছি তবে আমি মনে করি একটি গুরুত্বপূর্ণ বিষয়টি হাতছাড়া হচ্ছে।

আমার কেন এটি করা উচিত:

class Profile {
    public function deactivateProfile(Setting $setting)
    {
        $setting->isActive = false;
    }
}

আপনার করা উচিত নয়। কিন্তু নির্ভর করে না কারণ নির্ভরতা ইনজেকশন একটি খারাপ ধারণা। কারণ এটি এটি ভুল করছে।

কোড ব্যবহার করে এই জিনিসগুলি দেখতে দিন। আমরা এটি করতে যাচ্ছি:

$profile = new Profile();
$profile->deactivateProfile($setting);

যখন আমরা এটি থেকে একই জিনিসটি পেতে পারি:

$setting->isActive = false; // Deactivate profile

তাই অবশ্যই এটি সময়ের অপচয় হিসাবে মনে হচ্ছে। এটি আপনি যখন এইভাবে এটি করেন। এটি নির্ভরতা ইনজেকশন এর সেরা ব্যবহার নয়। এটি এমনকি কোনও শ্রেণীর সর্বোত্তম ব্যবহার নয়।

এখন কি যদি পরিবর্তে আমাদের এটি ছিল:

$profile = new Profile($setting);

$application = new Application($profile);

$application.start();

এবং এখন এটি applicationসক্রিয় ও নিষ্ক্রিয় করতে বিনামূল্যে profileএটি সম্পর্কে settingযে বিশেষভাবে এটি পরিবর্তন হচ্ছে সে সম্পর্কে বিশেষভাবে কিছু না জেনে । কেন যে ভাল? ক্ষেত্রে আপনার সেটিংস পরিবর্তন করতে হবে। এই applicationপরিবর্তনগুলি থেকে প্রাচীরটি বন্ধ হয়ে যায় তাই আপনি কোনও কিছু স্পর্শ করার সাথে সাথে সবকিছু ভেঙে না দেখে আপনার কোনও নিরাপদ স্থানে বাদাম ছাড়তে মুক্ত হন।

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

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

সময়ের সাথে সাথে আপনার বজায় রাখতে হবে এমন কোনও কিছুর চেষ্টা করুন এবং দেখুন এটি কোনও লাভ করে না কিনা।


6

একজন গ্রাহক হিসাবে, আপনি যখন নিজের গাড়ীতে কিছু করার জন্য কোনও যান্ত্রিককে ভাড়া করেন, আপনি কি সেই যান্ত্রিকটি কেবল স্ক্র্যাচ থেকে একটি গাড়ি তৈরি করবেন, তবে কেবল তখনই এটির সাথে কাজ করবেন? না, আপনি মেকানিককে যে গাড়িটি ব্যবহার করতে চান তা দিয়ে দিন

গ্যারেজের মালিক হিসাবে, আপনি যখন কোনও মেকানিককে গাড়ীতে কিছু করার নির্দেশ দেন, তখন কী আপনি মেকানিকটি তার নিজের স্ক্রু ড্রাইভার / রেঞ্চ / গাড়ির যন্ত্রাংশ তৈরি করবেন বলে আশা করেন? না, আপনি যন্ত্রটিকে তার যে অংশগুলি / সরঞ্জামগুলি ব্যবহার করতে হবে তা সরবরাহ করেন provide

কেন আমরা এই কাজ করি? ঠিক আছে, এটি সম্পর্কে চিন্তা করুন। আপনি একজন গ্যারেজ মালিক যিনি আপনার যান্ত্রিক হওয়ার জন্য কাউকে ভাড়া নিতে চান। আপনি তাদেরকে একজন যান্ত্রিক হতে শিখিয়ে দেবেন (= আপনি কোডটি লিখবেন)।

কি সহজ হতে চলেছে:

  • কোনও স্ক্রু ড্রাইভার ব্যবহার করে কীভাবে কোনও গাড়িতে কোনও স্পয়লার সংযুক্ত করতে হয় তা একটি মেকানিককে শিখান।
  • কোনও মেকানিককে গাড়ি তৈরি করতে, একটি স্পোয়েলার তৈরি করতে, একটি স্ক্রু ড্রাইভার তৈরি করতে এবং তারপরে নতুন নির্মিত স্ক্রু ড্রাইভারের সাথে সদ্য নির্মিত স্প্রেড্রাইভারের সাথে সদ্য নির্মিত স্পোলারটি সংযুক্ত করুন।

আপনার মেকানিকটি স্ক্র্যাচ থেকে সমস্ত কিছু তৈরি না করানোর ব্যাপক সুবিধা রয়েছে:

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

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

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

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


হ্যাঁ, নির্ভরতা হার্ডকোডিংয়ের পরিবর্তে লিখতে নির্ভরতা বিপরীতমুখী কিছুটা বেশি প্রচেষ্টা নেয়। হ্যাঁ, আরও টাইপ করতে পেরে বিরক্তিকর।

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

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


এটি সামগ্রিকভাবে কর্মক্ষমতাকে প্রভাবিত করে?

এটি অ্যাপ্লিকেশনটির রানটাইম কর্মক্ষমতা প্রভাবিত করে না। তবে এটি বিকাশকারীর বিকাশের সময় (এবং তাই কার্যকারিতা )কে ব্যাপকভাবে প্রভাবিত করে ।


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

12
আমি মনে করি পুরো গাড়ির জিনিসটি কিছুটা বিলোভিত এবং বিভ্রান্তিকর
Ewan

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

1
@ ফ্লাটার উদাহরণ সহ সমস্যাটি হ'ল আপনি অবশ্যই কোডটিতে কোনও সমস্যা মডেল করবেন না। এটি এইভাবে অপ্রাকৃত, বাধ্য, এবং উত্তরের চেয়ে আরও বেশি প্রশ্ন যুক্ত করে। এটি প্রদর্শন করার চেয়ে বিভ্রান্তি ও বিভ্রান্তির সম্ভাবনা তৈরি করে।
jpmc26

2
@ জিবিজেবাআনব: আমার উত্তর এমনকি কোনওভাবেই বহুরূপে বহুত্ববাদ নিয়ে আসে না। কোনও উত্তরাধিকার, ইন্টারফেস বাস্তবায়ন বা ধরণের আপ / ডাউনকাস্টিংয়ের অনুরূপ কিছু নেই। আপনি উত্তরটি পুরোপুরি ভুলভাবে লিখছেন।
উত্তেজনাকর

0

সমস্ত নিদর্শনগুলির মতো, ফুলে যাওয়া নকশাগুলি এড়াতে "কেন" জিজ্ঞাসা করা খুব বৈধ।

নির্ভরতা ইনজেকশনের জন্য, এটি সহজেই দু'জনের কথা চিন্তা করে দেখা যায়, তর্কযোগ্যভাবে, ওওপি ডিজাইনের সবচেয়ে গুরুত্বপূর্ণ দিকগুলি ...

কম মিলন

কম্পিউটার প্রোগ্রামিংয়ে সংযুক্ত হওয়া :

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

আপনি কম অর্জন করতে চান দম্পতি । দুটি বিষয় দৃ strongly়ভাবে মিলিত হওয়ার অর্থ এই যে আপনি যদি একটি পরিবর্তন করেন তবে আপনাকে সম্ভবত অন্যটি পরিবর্তন করতে হবে। একটিতে বাগ বা বিধিনিষেধগুলি সম্ভবত অন্যটিতে বাগ / সীমাবদ্ধতা প্ররোচিত করবে; ইত্যাদি।

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

উচ্চ সংহতি

সংহতি :

কম্পিউটার প্রোগ্রামিংয়ে সংহতি বলতে বোঝায় যে কোনও মডিউলের অভ্যন্তর উপাদানগুলি একত্রে অন্তর্ভূক্ত।

এটি মুদ্রার অন্য দিক। আপনি যদি কোডের একটি ইউনিট (একটি পদ্ধতি, একটি শ্রেণি, একটি প্যাকেজ ইত্যাদি) দেখুন তবে আপনি যতটা সম্ভব কম দায়িত্ব নেওয়ার জন্য সেই ইউনিটের ভিতরে সমস্ত কোড রাখতে চান।

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

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

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


-1

আপনি যখন এই সমস্যাগুলি সমাধান করেন তখন তারা যে সমস্যাগুলি সমাধান করতে পারে সেগুলি সমাধান করার জন্য আপনার কৌশলগুলি ব্যবহার করা উচিত। নির্ভরতা বিপরীতকরণ এবং ইনজেকশন আলাদা নয়।

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

আমরা কেন ফাংশনটির প্রয়োগকে আলাদা করতে চাই? এর দুটি প্রধান কারণ রয়েছে:

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

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

thing5 =  new MyThing5();
thing3 = new MyThing3(thing5, new MyThing10());

myApp = new MyApp(
    new MyAppDependency1(thing5, thing3),
    new MyAppDependency2(
        new Thing1(),
        new Thing2(new Thing3(thing5, new Thing4(thing5)))
    ),
    ...
    new MyAppDependency15(thing5)
);

এটি আপনাকে আপনার ক্লাসগুলি রেজিস্টার করতে দেয় এবং তারপরে আপনার জন্য নির্মাণটি করতে দেয়:

injector.register(Thing1); // Yes, you'd need some kind of actual class reference.
injector.register(Thing2);
...
injector.register(MyAppDepdency15);
injector.register(MyApp);

myApp = injector.create(MyApp); // The injector fills in all the construction parameters.

মনে রাখবেন যে নিবন্ধিত ক্লাসগুলি স্টেটলেস সিঙ্গেলন হতে পারে তবে এটি সবচেয়ে সহজ ।

সাবধানতা শব্দ

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

myAverageAboveMin()
{
    dbConn = new DbConnection("my connection string");
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", 5);
    dbQuery.Execute();
    myData = dbQuery.getAll();
    count = 0;
    total = 0;
    foreach (row in myData)
    {
        count++;
        total += row.x;
    }

    return total / count;
}

আমরা এই পদ্ধতির কিছু অংশের জন্য নির্ভরতা বিপরীত ব্যবহার করতে পারি:

class MyQuerier
{
    private _dbConn;

    MyQueries(dbConn) { this._dbConn = dbConn; }

    fetchAboveMin(min)
    {
        dbQuery = this._dbConn.makeQuery();
        dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
        dbQuery.setParam("min", min);
        dbQuery.Execute();
        return dbQuery.getAll();
    }
}


class Averager
{
    private _querier;

    Averager(querier) { this._querier = querier; }

    myAverageAboveMin(min)
    {
        myData = this._querier.fetchAboveMin(min);
        count = 0;
        total = 0;
        foreach (row in myData)
        {
            count++;
            total += row.x;
        }

        return total / count;
    }

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

class MyQuerier
{
    fetchAboveMin(dbConn, min)
    {
        dbQuery = dbConn.makeQuery();
        dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
        dbQuery.setParam("min", min);
        dbQuery.Execute();
        return dbQuery.getAll();
    }
}


class Averager
{
    averageData(myData)
    {
        count = 0;
        total = 0;
        foreach (row in myData)
        {
            count++;
            total += row.x;
        }

        return total / count;
    }

class StuffDoer
{
    private _querier;
    private _averager;

    StuffDoer(querier, averager)
    {
        this._querier = querier;
        this._averager = averager;
    }

    myAverageAboveMin(dbConn, min)
    {
        myData = this._querier.fetchAboveMin(dbConn, min);
        return this._averager.averageData(myData);
    }
}

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

এখন আমরা ক্যোয়ারিংয়ের পুরোপুরি স্বতন্ত্রভাবে গড় যুক্তি পরীক্ষা করতে পারি এবং আরও বিভিন্ন পরিস্থিতিতে আমরা এর ব্যবহার আরও কীভাবে করতে পারি। আমরা প্রশ্ন পারে কিনা আমরা এমনকি প্রয়োজন MyQuerierএবং Averagerবস্তু, এবং হয়ত উত্তর যে আমরা না যদি আমরা ইউনিট পরীক্ষা মনস্থ না StuffDoer, এবং ইউনিট টেস্টিং StuffDoerপুরোপুরি যুক্তিসঙ্গত হবে যেহেতু এটা এত শক্তভাবে ডাটাবেসের সাথে মিলিত হচ্ছে। এটি কেবলমাত্র ইন্টিগ্রেশন পরীক্ষাগুলি coverেকে রাখার জন্য আরও বোধগম্য হতে পারে। সেক্ষেত্রে আমরা হয়ত ভাল তৈরি করতে fetchAboveMinএবং averageDataঅচল পদ্ধতিতে চলেছি।


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

@ ডেভিড আর্নো হ্যাঁ, আপনি ঠিক বলেছেন আমি পরিভাষাটি সামঞ্জস্য করেছি।
jpmc26

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

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

1
@ jpmc26 তবে আপনার (মন্তব্যে) উদাহরণে ডাটাবেসটি শুরু করার জন্য নির্ভরতা হওয়ার দরকারও ছিল না। অবশ্যই শিথিলত মিলনের জন্য নির্ভরতা এড়ানো ভাল, তবে ডিআই নির্ভরতা নির্ভরতাগুলি বাস্তবায়নে ফোকাস করে।
তোলা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.