ধারকটির সাথে নির্ভরতা ইনজেকশন ব্যবহার এবং পরিষেবা লোকেটার ব্যবহারের মধ্যে পার্থক্য কী?


107

আমি বুঝতে পারি যে কোনও শ্রেণীর ভিতরে সরাসরি তাত্পর্যপূর্ণ নির্ভরতা খারাপ অভ্যাস হিসাবে বিবেচিত হয়। এটি দৃ tight়ভাবে দম্পতিরা যা কিছু করে যা টেস্টকে খুব শক্ত করে তোলে তা বোঝা যায়।

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

দুজনের মধ্যে পার্থক্য কী? কেন আমি একজনকে অন্যের থেকে বেছে নেব?


3
এই জিজ্ঞাসা করা হয়েছে (এবং বললেন) Stackoverflow উপর stackoverflow.com/questions/8900710/...
Kyralessa

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


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

উত্তর:


126

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

একটি ধারক যা নির্মাণকারী যুক্তির মাধ্যমে নির্ভরতা সরবরাহ করে সর্বাধিক স্পষ্টতা দেয়। আমরা ঠিক সামনে দেখতে পাচ্ছি যে কোনও বস্তুর জন্য একটি AccountRepositoryএবং এবং উভয়ই প্রয়োজন PasswordStrengthEvaluator। কোনও সার্ভিস লোকেটার ব্যবহার করার সময়, সেই তথ্যটি তত্ক্ষণাত কম দেখা যায়। আপনি অবিলম্বে এমন কোনও বিষয় দেখতে পাবেন যেখানে কোনও বস্তুর রয়েছে, ওহ, 17 নির্ভরতা, এবং নিজেকে বলবেন, "হুম, এটি অনেকটা মনে হচ্ছে there সেখানে কী চলছে?" কোনও সার্ভিস লোকেটারকে কল করা বিভিন্ন পদ্ধতিতে ছড়িয়ে পড়ে এবং শর্তযুক্ত যুক্তির পিছনে লুকিয়ে থাকতে পারে এবং আপনি বুঝতে পারবেন না যে আপনি একটি "গড ক্লাস" তৈরি করেছেন - যা সব কিছু করে। হতে পারে যে শ্রেণিটি 3 টি আরও ছোট ক্লাসগুলিতে আরও বেশি কেন্দ্রীভূত, এবং তাই আরও পরীক্ষামূলক into

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

এটি সম্পর্কে মার্ক সিমেনের নিবন্ধটির জন্য "সেরিবাস লোকেটার একটি অ্যান্টি-প্যাটার্ন" সন্ধান করুন। আপনি যদি নেট জগতে থাকেন তবে তার বইটি পান। এটা খুব ভালো.


1
গ্যারি ম্যাকলিন হলের সি # এর মাধ্যমে অভিযোজিত কোড সম্পর্কে আমি যে প্রশ্নটি পড়েছিলাম তা পড়েছি , যা এই উত্তরের সাথে বেশ ভালভাবে সাজায়। এতে সার্ভিস লোকেটার নিরাপদ হওয়ার মূল চাবিকাঠির মতো কিছু ভাল উপমা রয়েছে; যখন কোনও ক্লাসে হস্তান্তর করা হয়, এটি ইচ্ছায় নির্ভরতা তৈরি করতে পারে যা সম্ভবত খুঁজে পাওয়া সহজ হবে না।
ডেনিস

10
একটা জিনিষ আইএমও যোগ করা প্রয়োজন constructor supplied dependenciesবনাম service locatorযে সাবেক এক করা যেতে পারে , verfied কম্পাইল-টাইম যখন আধুনিক এক করতে শুধুমাত্র রানটাইম যাচাই করা।
andras

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

1
পরীক্ষার বিষয়ে - But that's more work than specifying dependencies in the object's constructor.আমি আপত্তি করতে চাই। কোনও পরিষেবা লোকেটারের সাথে আপনাকে কেবলমাত্র 3 টি নির্ভরতা নির্দিষ্ট করতে হবে যা আপনার পরীক্ষার জন্য আসলে প্রয়োজন। কনস্ট্রাক্টর-ভিত্তিক ডিআই দিয়ে আপনার 7 টি অব্যবহৃত থাকলেও তাদের সমস্ত 10 নির্দিষ্ট করতে হবে।
ভিলেক্স-

4
@ ভিলাক্স- আপনার যদি একাধিক অব্যবহৃত কনস্ট্রাক্টর প্যারামিটার থাকে তবে সম্ভবত আপনার শ্রেণি একক দায়িত্ব নীতি লঙ্ঘন করছে।
আরবি।

79

আপনি কল করুন এমন কোনও কারখানায় কর্মী যা জুতা তৈরি করে

আপনি জুতা একত্রিত করার জন্য দায়বদ্ধ এবং তাই এটি করার জন্য আপনার অনেক কিছুই প্রয়োজন।

  • চামড়া
  • পরিমাপের ফিতা
  • আঠা
  • পা ও নখ পরিচর্যা
  • হাতুড়ি
  • কাঁচি
  • জুতো লেইস

ইত্যাদি।

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

একটি পরিষেবা লোকেটার একটি ফোরম্যান সাহায্য করতে পারে আপনি আপনার যা প্রয়োজন পেতে ভালো হয়।

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

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

পরিষেবা লোকেটার

একজন নির্ভরতা ইনজেকশন (ডিআই) কনটেইনার সবকিছু যে সবাই দিনের শুরুতে দরকার ভরা পরার করে একটি বড় বাক্স মত হল।

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

লাইন ব্যবস্থাপকদের এখন দিনের জন্য তাদের দায়িত্ব পালনের জন্য যা প্রয়োজন তা আছে। তারা তাদের যা আছে তা নিয়ে যায় এবং তাদের অধীনস্থদের কাছে যা প্রয়োজন হয় তা দিয়ে দেয়।

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

আপনার ফোরম্যান এখন আপনার এবং অন্যান্য কর্মীদের কাছে যা প্রয়োজন তা ঠিক বিতরণ করে, আপনি এমনকি তাদের জন্য জিজ্ঞাসা না করেই।

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

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


45
এই 2 টি জিনিসের প্রত্যেকটি কী, দুর্দান্ত সু-চেহারাযুক্ত ডায়াগ্রামগুলির একটি দুর্দান্ত বর্ণনা! তবে এটি "কেন একজনকে অন্যের থেকে বেছে নেবেন" এই প্রশ্নের উত্তর দেয় না?
ম্যাথিউ এম।

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

5
@ ফ্র্যাঙ্কহপकिनস যদি আপনি আপনার ডিআই কনটেইনারের সাথে ইন্টারফেস / শ্রেণি নিবন্ধন বাদ দেন তবে আপনার কোডটি এখনও সংকলন করবে এবং এটি রানটাইমে তত্ক্ষণাত ব্যর্থ হবে।
কেনেথ কে।

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

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

10

ওয়েবে স্ক্রোল করার সময় আমি কয়েকটি অতিরিক্ত পয়েন্ট পেয়েছি:

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

4

আমি এই পার্টিতে দেরিতে আসছি তবে আমি প্রতিহত করতে পারছি না।

ধারকটির সাথে নির্ভরতা ইনজেকশন ব্যবহার এবং পরিষেবা লোকেটার ব্যবহারের মধ্যে পার্থক্য কী?

কখনও কখনও কিছুই না। কি পার্থক্য তোলে কি কি সম্পর্কে জানেন।

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

এর অর্থ কি যদি আপনি পরিষেবা লোকেটার এড়াতে চান তবে আপনি কোনও ধারক ব্যবহার করতে পারবেন না? না। আপনাকে কেবল ক্লায়েন্টদের ধারক সম্পর্কে জানতে হবে না। মূল পার্থক্য হ'ল যেখানে আপনি ধারকটি ব্যবহার করেন।

Clientপ্রয়োজন বলুন Dependency। পাত্রে রয়েছে ক Dependency

class Client { 
    Client() { 
        BeanFactory beanfactory = new ClassPathXmlApplicationContext("Beans.xml");
        this.dependency = (Dependency) beanfactory.getBean("dependency");        
    }
    Dependency dependency;
}

আমরা সবেমাত্র পরিষেবা লোকেটার প্যাটার্নটি অনুসরণ করেছি কারণ Clientকীভাবে সন্ধান করতে হয় তা জানে Dependency। নিশ্চিত যে এটি একটি হার্ড কোডড ব্যবহার করেছে ClassPathXmlApplicationContextতবে আপনি ইনজেকশন দিলেও Clientকল করেছেন কারণ আপনার কাছে এখনও একটি সার্ভিস লোকেটার রয়েছে beanfactory.getBean()

পরিষেবা লোকেটার এড়ানোর জন্য আপনাকে এই ধারকটি ত্যাগ করতে হবে না। আপনি শুধু এটা থেকে বের সরানো আছে Clientযাতে Clientএটি সম্পর্কে জানে না।

class EntryPoint { 
    public static void main(String[] args) {
        BeanFactory beanfactory = new ClassPathXmlApplicationContext("Beans.xml");
        Client client = (Client) beanfactory.getBean("client");

        client.start();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="dependency" class="Dependency">
    </bean>

    <bean id="client" class="Client">
        <constructor-arg value="dependency" />        
    </bean>
</beans>

খেয়াল করুন কীভাবে Clientএখন ধারনাটি নেই তার ধারণা নেই:

class Client { 
    Client(Dependency dependency) { 

        this.dependency = dependency;        
    }
    Dependency dependency;
}

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

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

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


1

আমি মনে করি যে কোনও পরিষেবা লোকেটারের চেয়ে ডিআই কনটেইনারের চেয়ে দু'জনের মধ্যে পার্থক্যটি বোঝার সবচেয়ে সহজ উপায় হ'ল আমরা কেন প্রথম স্থানে নির্ভরতা বিপরীতে করি about

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

আসুন নীচের ক্লাসটি দেখুন:

public class MySpecialStringWriter
{
  private readonly IOutputProvider outputProvider;
  public MySpecialFormatter(IOutputProvider outputProvider)
  {
    this.outputProvider = outputProvider;
  }

  public void OutputString(string source)
  {
    this.outputProvider.Output("This is the string that was passed: " + source);
  }
}

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

পরিষেবা লোকেটার সহ একই ক্লাসে একবার দেখুন:

public class MySpecialStringWriter
{
  private readonly ServiceLocator serviceLocator;
  public MySpecialFormatter(ServiceLocator serviceLocator)
  {
    this.serviceLocator = serviceLocator;
  }

  public void OutputString(string source)
  {
    this.serviceLocator.OutputProvider.Output("This is the string that was passed: " + source);
  }
}

এখন আমি সার্ভিস লোকেটারকে নির্ভরতা হিসাবে যুক্ত করেছি। এখানে সমস্যাগুলি যা তাত্ক্ষণিকভাবে সুস্পষ্ট:

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

তাহলে আমরা কেন পরিষেবা লোকেটারকে একটি স্ট্যাটিক ক্লাস করব না? এর কটাক্ষপাত করা যাক:

public class MySpecialStringWriter
{
  public void OutputString(string source)
  {
    ServiceLocator.OutputProvider.Output("This is the string that was passed: " + source);
  }
}

এটা অনেক সহজ, তাই না?

ভুল।

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

এই ক্লাসটি পরীক্ষা করার চেষ্টা করা যাক। পরীক্ষার জন্য আমাদের আলাদা আলাদা আইওআউটপুটপ্রভাইডার প্রয়োজন। আমরা কীভাবে পরীক্ষা লিখি?

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

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

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

কেবলমাত্র সার্ভিস লোকেটারগুলিতে একটি অ্যাপ্লিকেশনে সংযোগ বাড়ায় এবং অন্যান্য বিকাশকারীদের উচ্চ যুগল কোড লিখতে উত্সাহিত করে


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

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

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

প্রাথমিকভাবে হ্যাঁ, তবে আপনি নির্ভরতা নিচ্ছেন তা উপলব্ধি না করে আপনি কোনও পরিষেবা লোকেটারের সাথে নির্ভরতা নিতে পারেন। যে কারণে আমরা প্রথম স্থানে নির্ভরতা বিপর্যয় করি তার একটি বড় অংশকে পরাস্ত করে। একটি শ্রেণি A এবং B এর বৈশিষ্ট্যগুলির উপর নির্ভর করে, অন্যটি বি এবং সি এর উপর নির্ভর করে হঠাৎ সার্ভিস লোকেটার godশ্বর শ্রেণিতে পরিণত হয়। ডিআই কন্টেইনারটি করে না এবং দুটি শ্রেণি যথাক্রমে কেবলমাত্র এ এবং বি এবং বি এবং সি এর উপর নির্ভরশীল। এটি তাদের একশত গুণ সহজ করে তোলে। পরিষেবাদি লোকেরা এগুলি ছদ্মবেশী যে তারা ডিআই হিসাবে একই প্রদর্শিত হবে কিন্তু তারা তা নয়।
স্টিফেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.