নির্ভরতা বিপরীত নীতিটি কী এবং এটি কেন গুরুত্বপূর্ণ?


177

নির্ভরতা বিপরীত নীতিটি কী এবং এটি কেন গুরুত্বপূর্ণ?



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

উত্তর:


106

এই দস্তাবেজটি দেখুন: নির্ভরতা বিপরীতমুখী মূলনীতি

এটি মূলত বলে:

  • উচ্চ স্তরের মডিউলগুলি নিম্ন-স্তরের মডিউলগুলির উপর নির্ভর করে না। উভয়েরই বিমূর্ততার উপর নির্ভর করা উচিত।
  • বিমূর্ততা কখনই বিশদের উপর নির্ভর করে না। বিবরণ বিমূর্ততা উপর নির্ভর করা উচিত।

সংক্ষেপে এটি কেন গুরুত্বপূর্ণ, তা পরিবর্তনগুলি ঝুঁকিপূর্ণ এবং বাস্তবায়নের পরিবর্তে কোনও ধারণার উপর নির্ভর করে আপনি কল সাইটগুলিতে পরিবর্তনের প্রয়োজনীয়তা হ্রাস করেন।

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

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


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

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

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

1
তাহলে নিয়ন্ত্রণের বিপরীতটি কী? নির্ভরতা বিপর্যয় অর্জনের উপায়?
ব্যবহারকারী 20358

2
@ রোজারিও, নীচে ডেরেক গ্রেয়ার প্রতিক্রিয়া দেখুন, তিনি এটি ব্যাখ্যা করেছেন। আফাইক, ডিআইপি বলেছে যে এটি এ, যিনি এ-এর প্রয়োজনের আদেশ দেন, এবং বি-কে নয় যা এ-এর প্রয়োজন বলে। সুতরাং, যে ইন্টারফেসটি A এর দরকার তা বি দ্বারা দেওয়া উচিত নয়, তবে এ এর ​​জন্য
Ejaenv

144

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

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

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

ডিপেন্ডেন্সি ইনভার্সন নীতিটি যা উল্লেখ করে না তা হ'ল ইন্টারফেসের (যেমন মাই সার্ভিস → [আইলোগার ⇐ লগার]) ব্যবহারের মাধ্যমে নির্ভরতা বিমূ .় করার সহজ অনুশীলন। যদিও নির্ভরতার নির্দিষ্ট প্রয়োগের বিশদ থেকে এটি কোনও উপাদানকে ডিকুপল করে, এটি গ্রাহক এবং নির্ভরতার মধ্যে সম্পর্ককে উল্টে দেয় না (উদাঃ [মাই সার্ভিস → আইএমআই সার্ভিস লোগার] ger লগার)।

নির্ভরতা বিপরীতমূলক নীতির গুরুত্ব নির্ধারণ করা যেতে পারে সফ্টওয়্যার উপাদানগুলি পুনরায় ব্যবহার করতে সক্ষম হওয়ার একক লক্ষ্যে যা তাদের কার্যকারিতার একটি অংশের জন্য (লগিং, বৈধকরণ ইত্যাদি) বাহ্যিক নির্ভরতার উপর নির্ভর করে re

পুনরায় ব্যবহারের এই সাধারণ লক্ষ্যের মধ্যে আমরা দুটি উপ-প্রকার পুনঃব্যবহারের বর্ণনা করতে পারি:

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

  2. একটি বিকশিত প্রসঙ্গের মধ্যে সফ্টওয়্যার উপাদান ব্যবহার করে (যেমন আপনি ব্যবসায়-যুক্তিযুক্ত উপাদানগুলি বিকাশ করেছেন যা প্রয়োগের বিশদগুলি যেখানে বিকশিত হচ্ছে এমন একাধিক সংস্করণ জুড়ে একই থাকে) across

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

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

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

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

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


17
ধন্যবাদ। আমি এখন দেখছি কিভাবে আমার উত্তরটি বিন্দুটি মিস করে। মধ্যে পার্থক্য MyService → [ILogger ⇐ লগার] এবং [MyService → IMyServiceLogger] ⇐ লগার সূক্ষ্ম কিন্তু গুরুত্বপূর্ণ।
প্যাট্রিক ম্যাকএলহানি

2
একই লাইনে এটি খুব ভালভাবে এখানে ব্যাখ্যা করা হয়েছে: lostechies.com/derickbailey/2011/09/22/…
এজেনভ

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

4
@ ক্যাস্পার লিওন নিলসন - ডিআইপি-র ডিআইয়ের সাথে কোনও সম্পর্ক নেই এগুলি প্রতিশব্দ বা সমতুল্য ধারণা নয়।
টিএসমিথ

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

13

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

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

নির্ভরতা বিপর্যয় নীতিতে বলা হয়েছে যে:

  • উচ্চ স্তরের মডিউলগুলি নিম্ন স্তরের মডিউলগুলির উপর নির্ভর করে না। উভয়েরই বিমূর্ততার উপর নির্ভর করা উচিত।
  • বিমূর্ততা বিশদ উপর নির্ভর করবে না। বিবরণ বিমূর্ততা উপর নির্ভর করা উচিত।

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


11

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

Ditionতিহ্যবাহী স্তরযুক্ত আর্কিটেকচার

Ditionতিহ্যগতভাবে একটি স্তরযুক্ত আর্কিটেকচার ইউআই ব্যবসায়ের স্তরের উপর নির্ভরশীল এবং এটি পরিবর্তিতভাবে ডেটা অ্যাক্সেস স্তরের উপর নির্ভরশীল।

আপনাকে স্তর, প্যাকেজ বা লাইব্রেরি বুঝতে হবে। কোডটি কেমন হবে তা দেখুন।

আমাদের ডেটা অ্যাক্সেস লেয়ারের জন্য একটি গ্রন্থাগার বা প্যাকেজ থাকবে।

// DataAccessLayer.dll
public class ProductDAO {

}

এবং অন্য একটি লাইব্রেরি বা প্যাকেজ স্তর ব্যবসায়িক যুক্তি যা ডেটা অ্যাক্সেস লেয়ারের উপর নির্ভর করে।

// BusinessLogicLayer.dll
using DataAccessLayer;
public class ProductBO { 
    private ProductDAO productDAO;
}

নির্ভরতা বিপরীতকরণ সহ স্তরযুক্ত আর্কিটেকচার

নির্ভরতা বিপর্যয় নিম্নলিখিতটি নির্দেশ করে:

উচ্চ-স্তরের মডিউলগুলি নিম্ন-স্তরের মডিউলগুলির উপর নির্ভর করে না। উভয়ের বিমূর্ততা উপর নির্ভর করা উচিত।

বিমূর্ততা বিশদ উপর নির্ভর করবে না। বিবরণ বিমূর্ততা উপর নির্ভর করা উচিত।

উচ্চ-স্তরের মডিউল এবং নিম্ন স্তরের কী কী? গ্রন্থাগার বা প্যাকেজগুলির মতো চিন্তাভাবনা মডিউলগুলি, উচ্চ-স্তরের মডিউলগুলি হ'ল traditionতিহ্যগতভাবে নির্ভরতা এবং নিম্ন স্তরের যার উপর তারা নির্ভর করে।

অন্য কথায়, মডিউল উচ্চ স্তরটি যেখানে ক্রিয়াটি চালিত হয় এবং নিম্ন স্তরের যেখানে কর্ম সঞ্চালিত হয়।

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

কল্পনা করুন যে আমরা আমাদের কোডটি নিম্নরূপে গ্রহণ করেছি:

আমাদের ডেটা অ্যাক্সেস লেয়ারের জন্য একটি গ্রন্থাগার বা প্যাকেজ থাকবে যা বিমূর্তি সংজ্ঞায়িত করে।

// DataAccessLayer.dll
public interface IProductDAO
public class ProductDAO : IProductDAO{

}

এবং অন্য একটি লাইব্রেরি বা প্যাকেজ স্তর ব্যবসায়িক যুক্তি যা ডেটা অ্যাক্সেস লেয়ারের উপর নির্ভর করে।

// BusinessLogicLayer.dll
using DataAccessLayer;
public class ProductBO { 
    private IProductDAO productDAO;
}

যদিও আমরা ব্যবসায় এবং ডেটা অ্যাক্সেসের মধ্যে কোনও বিমূর্ততা নির্ভরতার উপর নির্ভরশীল।

নির্ভরতা বিপর্যয় পেতে, দৃistence়তা ইন্টারফেসটি মডিউল বা প্যাকেজে সংজ্ঞায়িত করতে হবে যেখানে এই উচ্চ স্তরের যুক্তি বা ডোমেনটি নিম্ন-স্তরের মডিউলটিতে নয়।

প্রথমে ডোমেন স্তরটি কী তা নির্ধারণ করুন এবং এর যোগাযোগের বিমূর্ততা দৃistence়তা সংজ্ঞায়িত করা হয়েছে।

// Domain.dll
public interface IProductRepository;

using DataAccessLayer;
public class ProductBO { 
    private IProductRepository productRepository;
}

অধ্যবসায় স্তর ডোমেনের উপর নির্ভর করে, যদি কোনও নির্ভরতা সংজ্ঞায়িত করা হয় তবে এখনই উল্টে যাবে।

// Persistence.dll
public class ProductDAO : IProductRepository{

}


(সূত্র: xurxodev.com )

নীতি গভীর করা

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

কিন্তু কেন আমরা একটি নির্ভরতা উল্টে না? নির্দিষ্ট উদাহরণের বাইরে মূল উদ্দেশ্য কী?

যেমন সাধারণত এগুলি সবচেয়ে স্থিতিশীল জিনিসগুলিকে, যা কম স্থিতিশীল জিনিসের উপর নির্ভর করে না, আরও ঘন ঘন পরিবর্তনের অনুমতি দেয়।

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

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

আর্কিটেকচারের

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

পরিষ্কার আর্কিটেকচার

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


(সূত্র: অষ্টম আলো ডটকম )

ষড়ভুজ আর্কিটেকচার

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


আমি কী বলতে চাইছি তা নিশ্চিত নই, তবে এই বাক্যটি অন্তর্নিহিত: "তবে আমরা যে পদ্ধতি গ্রহণ করি সে অনুসারে আমরা বিনিয়োগের উপর নির্ভরশীল নির্ভরতা, তবে একটি বিমূর্ততা ভুলভাবে প্রয়োগ করতে পারি" " সম্ভবত আপনি ঠিক করতে চান?
মার্ক আমেরিকা

9

আমার কাছে, নির্ভরশীলতা উল্টে দেওয়া নীতিমালা, যেমন অফিশিয়াল নিবন্ধে বর্ণিত হয়েছে , প্রকৃতপক্ষে কম পুনরায় ব্যবহারযোগ্য মডিউলগুলির পুনঃব্যবহারযোগ্যতা বৃদ্ধি করার পাশাপাশি সি ++ ভাষায় কোনও সমস্যা সমাধানের উপায় work

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

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

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


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

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

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

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

1
ইউআই স্ক্রিনটি অবশ্যই উচ্চ স্তরের মডিউল নয় বা কোনও অ্যাপ্লিকেশনের জন্য হওয়া উচিত নয়। সর্বাধিক স্তরের মডিউলগুলি এমন যেগুলিতে বিধি বিধান থাকে। একটি সর্বোচ্চ স্তরের মডিউল পুনরায় ব্যবহারযোগ্যতার জন্য তার সম্ভাব্যতা দ্বারা সংজ্ঞায়িত হয় না। এই নিবন্ধে আঙ্কেল বব এর সহজ ব্যাখ্যা পরীক্ষা করুন: ববরের blog.cleancoder.com/uncle-bob/2016/01/04/…
হুমবাবা

8

মূলত এটি বলে:

শ্রেণীর বিমূর্তকরণের উপর নির্ভর করা উচিত (উদাহরণস্বরূপ ইন্টারফেস, বিমূর্ত শ্রেণি), নির্দিষ্ট বিবরণ নয় (বাস্তবায়ন)।


এটা কি সহজ হতে পারে? লম্বা নিবন্ধ এবং এমনকি বই যেমন ডেরেকগ্রির উল্লেখ করেছেন? আমি আসলে সহজ উত্তর খুঁজছিলাম, তবে এটি অবিশ্বাস্য যদি এটি সহজ হয়: ডি
দারিয়াস.ভি

1
@ দারিয়াস-ভি এটি "অ্যাবস্ট্রাকশন ব্যবহার করুন" বলার অন্য সংস্করণ নয়। ইন্টারফেসের মালিকানা সম্পর্কে এটি। অধ্যক্ষ বলেছেন ক্লায়েন্টের (উচ্চ স্তরের উপাদানগুলি) ইন্টারফেসগুলি সংজ্ঞায়িত করা উচিত এবং নিম্ন স্তরের উপাদানগুলি তাদের প্রয়োগ করা উচিত।
বোরান

6

ভাল উত্তর এবং ভাল উদাহরণ ইতিমধ্যে অন্যদের দ্বারা এখানে দেওয়া হয়েছে।

কারন চোবান গুরুত্বপূর্ণ কারণ এটি OO যেমন পণ্য-নীতি "ঢিলেঢালাভাবে মিলিত নকশা" নিশ্চিত করে হয়।

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

আপনি চান যে আপনার 'শীর্ষ-স্তরের' অবজেক্টগুলি খুব স্থিতিশীল এবং পরিবর্তনের জন্য ভঙ্গুর না হওয়ার জন্য, তাই আপনার নির্ভরতাগুলি উল্টাতে হবে।


6
জাভা বা। নেট কোডের জন্য ডিআইপি ঠিক কীভাবে তা করে? এই ভাষাগুলিতে, সি ++ এর বিপরীতে, নিম্ন-স্তরের মডিউল প্রয়োগের পরিবর্তনের জন্য এটি ব্যবহার করা উচ্চ-স্তরের মডিউলগুলির পরিবর্তন দরকার হয় না। কেবলমাত্র পাবলিক ইন্টারফেসের পরিবর্তনগুলিই রিপল-থ্রো হতে পারে তবে উচ্চ স্তরে সংজ্ঞায়িত বিমূর্ততাটিও পরিবর্তন করতে হবে।
Rogério

5

নির্ভরতা বিপরীতমুখী মূলনীতিটি বর্ণনা করার আরও সুস্পষ্ট উপায় হ'ল:

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

অর্থ্যাৎ Logicলোকেরা সাধারণত যেমন করে আপনার ক্লাস বাস্তবায়নের পরিবর্তে :

class Dependency { ... }
class Logic {
    private Dependency dep;
    int doSomething() {
        // Business logic using dep here
    }
}

আপনার কিছু করা উচিত:

class Dependency { ... }
interface Data { ... }
class DataFromDependency implements Data {
    private Dependency dep;
    ...
}
class Logic {
    int doSomething(Data data) {
        // compute something with data
    }
}

Dataএবং DataFromDependencyএকই মডিউলে থাকা উচিত Logic, সাথে নয়Dependency

কেন এমন করবেন?

  1. দুটি ব্যবসায়ের লজিক মডিউলগুলি এখন decoupled। যখন Dependencyপরিবর্তন হয়, আপনার পরিবর্তন করার প্রয়োজন হয় নাLogic
  2. কী কী Logicতা বোঝা খুব সহজ কাজ: এটি কেবল এটিডিটির মতো দেখায় like
  3. Logicএখন আরও সহজে পরীক্ষা করা যায়। আপনি এখন Dataনকল ডেটা দিয়ে সরাসরি ইনস্ট্যান্ট করতে পারেন এবং এতে পাস করতে পারেন m নকল বা জটিল পরীক্ষার স্ক্যাফোল্ডিংয়ের প্রয়োজন নেই।

আমি এটা ঠিক মনে করি না। যদি DataFromDependency, যা সরাসরি উল্লেখ করে Dependency, একই মডিউলে থাকে Logicতবে Logicমডিউলটি এখনও Dependencyসংকলনের সময় মডিউলটির উপর সরাসরি নির্ভর করে । পের আঙ্কেল বব নীতি সম্পর্কে ব্যাখ্যা , এড়ানো এটাই ডিআইপি-র পুরো বিষয়। বরং, চোবান উপভোগ করতে চান, Dataহিসাবে একই মডিউল হওয়া উচিত Logic, কিন্তু DataFromDependencyহিসাবে একই মডিউল হওয়া উচিত Dependency
মার্ক আমেরিকা

3

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

Traditionalতিহ্যবাহী চেহারা ব্যবহার করে সিউডোকোড উদাহরণ:

class Service {
    Database database;
    init() {
        database = FrameworkSingleton.getService("database");
    }
}

আইওসি ব্যবহার করে অনুরূপ কোড:

class Service {
    Database database;
    init(database) {
        this.database = database;
    }
}

আইওসির সুবিধাগুলি হ'ল:

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

নির্ভরতা বিপরীতমুখী মূলনীতি এবং নিয়ন্ত্রণের বিপরীতটি কি একই জিনিস?
পিটার মর্টেনসেন

3
ডিআইপি-তে "বিপর্যয়" নিয়ন্ত্রণের বিপরীতের মতো নয় । প্রথমটি সংকলন-সময় নির্ভরতা সম্পর্কে, যখন দ্বিতীয়টি রানটাইম সময়ে পদ্ধতিগুলির মধ্যে নিয়ন্ত্রণের প্রবাহ সম্পর্কে।
Rogério

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

1
ইতিমধ্যে @ রোগারিও বলেছিলেন, ডিআইপি ডিআই / আইওসি নয়। এই উত্তরটি ভুল আইএমও
জেরাদেভ

1

নির্ভরতা বিপরীতকরণের বিষয়টি হ'ল পুনরায় ব্যবহারযোগ্য সফ্টওয়্যার তৈরি করা।

ধারণাটি হ'ল একে অপরের উপর নির্ভর করে দুটি টুকরো কোডের পরিবর্তে তারা কিছু বিমূর্ত ইন্টারফেসের উপর নির্ভর করে। তারপরে আপনি অন্যটি ছাড়াই উভয় অংশ পুনরায় ব্যবহার করতে পারেন।

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

এই সিউডোকোডটি কল্পনা করুন ...

public class MyClass
{
  public Service myService = ServiceLocator.service;
}

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

public class MyClass
{
  public IService myService;
}

এখন, মাইক্লাস একটি একক ইন্টারফেস, আইএসএসআর ইন্টারফেসের উপর নির্ভর করে। আমরা আইওসি পাত্রে আসলে সেই ভেরিয়েবলের মান সেট করতে দেব।

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

আরও ভাল, আপনাকে মাই সার্ভিসের নির্ভরতা এবং সেই নির্ভরতাগুলির নির্ভরতা এবং ... ঠিক আছে, আপনাকে টেনে আনতে হবে না।


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

1

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

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

নির্ভরতা বিপরীত নীতির "উচ্চ স্তরের" অর্থ "আরও গুরুত্বপূর্ণ"।


1
এটি একটি উল্লেখযোগ্য ভাল উপমা। অনেকটাই, ডিআইসির আওতায় উচ্চ-স্তরের উপাদানগুলি এখনও নিম্ন- স্তরেরগুলির উপর রানটাইম নির্ভর করে , এই সাদৃশ্যগুলিতে উচ্চ-স্তরের পরিকল্পনাগুলি নিম্ন স্তরের পরিকল্পনার উপর নির্ভর করে। তবে এছাড়াও, ডিআইসির আওতায় এটি নিম্ন-স্তরের পরিকল্পনাগুলি যা উচ্চ-স্তরের পরিকল্পনাগুলির উপর সঙ্কলনের সময় নির্ভর করে, আপনার উপমা অনুসারে এটি নিম্ন স্তরের পরিকল্পনা গঠন উচ্চ-স্তরের পরিকল্পনার উপর নির্ভর করে।
মার্ক আমেরিকা

0

আমি দেখতে পাচ্ছি উপরের উত্তরগুলিতে ভাল ব্যাখ্যা দেওয়া হয়েছে। তবে আমি সাধারণ উদাহরণ সহ কিছু সহজ ব্যাখ্যা দিতে চাই।

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

এটি কীভাবে অর্জন করবেন: বিমূর্ততার মাধ্যমে

নির্ভরতা বিপরীত ছাড়াই:

 class Student {
    private Address address;

    public Student() {
        this.address = new Address();
    }
}
class Address{
    private String perminentAddress;
    private String currentAdrress;

    public Address() {
    }
} 

উপরের কোড স্নিপেটে, ঠিকানা অবজেক্টটি হার্ড-কোডড। পরিবর্তে যদি আমরা নির্ভরতা বিপরীতমুখী ব্যবহার করতে পারি এবং কনস্ট্রাক্টর বা সেটার পদ্ধতির মধ্য দিয়ে অ্যাড্রেস অবজেক্টটি ইনজেক্ট করতে পারি। দেখা যাক.

নির্ভরতা বিপরীতে:

class Student{
    private Address address;

    public Student(Address address) {
        this.address = address;
    }
    //or
    public void setAddress(Address address) {
        this.address = address;
    }
}

-1

নির্ভরতা বিপরীতমুখী: সংক্ষেপে নয়, বিমূর্ততার উপর নির্ভর করে।

নিয়ন্ত্রণের বিপরীতে: প্রধান বনাম বিমূর্তি এবং কীভাবে প্রধান সিস্টেমগুলির আঠালো।

ডিআইপি এবং আইওসি

এটি সম্পর্কে ভাল কথা পোস্ট করা হয়:

https://coderstower.com/2019/03/26/dependency-inversion-why-you-shouldnt-avoid-it/

https://coderstower.com/2019/04/02/main-and-abstraction-the-decoupled-peers/

https://coderstower.com/2019/04/09/inversion-of-control-putting-all-together/


-1

ধরা যাক যে আমাদের দুটি শ্রেণি রয়েছে: EngineerএবংProgrammer :

ক্লাস ইঞ্জিনিয়ারের প্রোগ্রামার ক্লাসের উপর নির্ভরতা থাকে, নীচের মতো:

class Engineer () {

    fun startWork(programmer: Programmer){
        programmer.work()
    }
}

class Programmer {

    fun work(){
        //TODO Do some work here!
    }
}

এই উদাহরণে শ্রেণীর Engineerআমাদের Programmerক্লাসের উপর নির্ভরতা রয়েছে । আমার যদি পরিবর্তন করতে হয় তবে কী হবেProgrammer ?

অবশ্যই আমারও এটি পরিবর্তন করা দরকার Engineer। (বাহ, এই সময়েOCP খুব লঙ্ঘন করা হয়)

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

দ্রষ্টব্য: DependencyInjectionআমাদের করতে DIPএবং SRPখুব সহায়তা করতে পারে ।


-1

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

বলুন, আপনি একটি ছোট প্রোগ্রাম কনসোল আই / ওয়ের মাধ্যমে একটি স্ট্রিংকে বেস 6464 ফর্ম্যাটে রূপান্তর করতে চান । এখানে নির্বিকার পন্থা:

class Program
{
    static void Main(string[] args)
    {
        /*
         * BadEncoder: High-level class *contains* low-level I/O functionality.
         * Hence, you'll have to fiddle with BadEncoder whenever you want to change
         * the I/O mode or details. Not good. A good encoder should be I/O-agnostic --
         * problems with I/O shouldn't break the encoder!
         */
        BadEncoder.Run();            
    }
}

public static class BadEncoder
{
    public static void Run()
    {
        Console.WriteLine(Convert.ToBase64String(Encoding.UTF8.GetBytes(Console.ReadLine())));
    }
}    

ডিআইপি মূলত বলেছে যে উচ্চ-স্তরের উপাদানগুলি নিম্ন-স্তরের বাস্তবায়নের উপর নির্ভরশীল হওয়া উচিত নয়, যেখানে রবার্ট সি মার্টিনের ("ক্লিন আর্কিটেকচার") অনুসারে "স্তর" I / O থেকে দূরত্ব। তবে কীভাবে আপনি এই পরিস্থিতি থেকে বেরিয়ে আসবেন? কীভাবে কীভাবে এটি বাস্তবায়িত হয় তা বিরক্ত না করে কেবলমাত্র কেন্দ্রীয় এনকোডারকে কেবল ইন্টারফেসের উপর নির্ভরশীল করে তুলে:

class Program
{
    static void Main(string[] args)
    {           
        /* Demo of the Dependency Inversion Principle (= "High-level functionality
         * should not depend upon low-level implementations"): 
         * You can easily implement new I/O methods like
         * ConsoleReader, ConsoleWriter without ever touching the high-level
         * Encoder class!!!
         */            
        GoodEncoder.Run(new ConsoleReader(), new ConsoleWriter());        }
}

public static class GoodEncoder
{
    public static void Run(IReadable input, IWriteable output)
    {
        output.WriteOutput(Convert.ToBase64String(Encoding.ASCII.GetBytes(input.ReadInput())));
    }
}

public interface IReadable
{
    string ReadInput();
}

public interface IWriteable
{
    void WriteOutput(string txt);
}

public class ConsoleReader : IReadable
{
    public string ReadInput()
    {
        return Console.ReadLine();
    }
}

public class ConsoleWriter : IWriteable
{
    public void WriteOutput(string txt)
    {
        Console.WriteLine(txt);
    }
}

নোট করুন যে GoodEncoderআই / ও মোডটি পরিবর্তনের জন্য আপনাকে স্পর্শ করার দরকার নেই - যে শ্রেণিটি I / O ইন্টারফেসগুলি এটি জানে তাতে খুশি; কোনও নিম্ন-স্তরের বাস্তবায়ন IReadableএবং IWriteableএটি কখনই বিরক্ত করবে না।


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

-2

ডিপেন্ডেন্সি ইনভার্সন প্রিন্সিপাল (ডিআইপি) বলেছে

i) উচ্চ স্তরের মডিউলগুলি নিম্ন-স্তরের মডিউলগুলির উপর নির্ভর করে না। উভয়েরই বিমূর্ততার উপর নির্ভর করা উচিত।

ii) বিমূর্ততা কখনই বিশদের উপর নির্ভর করে না। বিবরণ বিমূর্ততা উপর নির্ভর করা উচিত।

উদাহরণ:

    public interface ICustomer
    {
        string GetCustomerNameById(int id);
    }

    public class Customer : ICustomer
    {
        //ctor
        public Customer(){}

        public string GetCustomerNameById(int id)
        {
            return "Dummy Customer Name";
        }
    }

    public class CustomerFactory
    {
        public static ICustomer GetCustomerData()
        {
            return new Customer();
        }
    }

    public class CustomerBLL
    {
        ICustomer _customer;
        public CustomerBLL()
        {
            _customer = CustomerFactory.GetCustomerData();
        }

        public string GetCustomerNameById(int id)
        {
            return _customer.GetCustomerNameById(id);
        }
    }

    public class Program
    {
        static void Main()
        {
            CustomerBLL customerBLL = new CustomerBLL();
            int customerId = 25;
            string customerName = customerBLL.GetCustomerNameById(customerId);


            Console.WriteLine(customerName);
            Console.ReadKey();
        }
    }

দ্রষ্টব্য: শ্রেণীর ইন্টারফেস বা বিমূর্ত শ্রেণির মতো বিমূর্তকরণের উপর নির্ভর করা উচিত, নির্দিষ্ট বিবরণ নয় (ইন্টারফেসের প্রয়োগ)।

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