নির্ভরতা ইনজেকশন এবং একক ডিজাইন প্যাটার্ন


91

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

উদাহরণস্বরূপ লগার। আমি Logger.GetInstance().Log(...) তবে এটির পরিবর্তে, লগারের উদাহরণ সহ আমার তৈরি প্রতিটি ক্লাসটি কেন ইনজেক্ট করা দরকার??

উত্তর:


67

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

পরীক্ষার যোগ্যতার জন্য অবজেক্ট-ওরিয়েন্টড ডিজাইনে এই উপস্থাপনাটি দেখুন এবং আপনি দেখবেন কেন সিলেটলেটগুলি খারাপ।

সিঙ্গলটনের সমস্যা হ'ল তারা এমন একটি বিশ্বব্যাপী রাষ্ট্রের প্রতিনিধিত্ব করে যা পূর্বাভাস দেওয়া কঠিন, বিশেষত পরীক্ষায়।

মনে রাখবেন যে কোনও অবজেক্টটি ডি-ফ্যাক্টো সিঙ্গলটন হতে পারে তবে তারপরে নির্ভর করে ইনজেকশন-ইনজেকশনের মাধ্যমে প্রাপ্ত হতে পারে Singleton.getInstance()

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


89

সিলেটলেটগুলি সাম্যবাদের মতো: এগুলি দুটিই কাগজে দুর্দান্ত লাগে তবে বাস্তবে সমস্যাগুলির সাথে এটি বিস্ফোরিত হয়।

সিঙ্গেলটন প্যাটার্নটি অবজেক্টগুলিতে অ্যাক্সেসের স্বাচ্ছন্দ্যে একটি অপ্রাসঙ্গিক জোর দেয়। এটি প্রতিটি গ্রাহক একটি অ্যাপডোমেন-স্কোপড অবজেক্ট ব্যবহার করে প্রয়োজনীয় প্রয়োগের পরিবর্তে সম্পূর্ণ প্রেক্ষাপটকে রক্ষা করে implement এটি GetInstance()ঠিক শূন্য অভিব্যক্তিযুক্ত শক্তি যোগ করার সময় আপনার ক্লাসগুলিতে (ডাকে ) অবকাঠামোগত জ্ঞান এম্বেড করে। এটি প্রকৃতপক্ষে আপনার অভিব্যক্তি শক্তিটিকে হ্রাস করে, কারণ আপনি এক শ্রেণীর দ্বারা ব্যবহৃত সকলের জন্য এটি পরিবর্তন না করে প্রয়োগ বাস্তবায়ন করতে পারবেন না । আপনি কেবল কার্যকারিতার এক-অফ টুকরা যোগ করতে পারবেন না।

এছাড়াও, যখন শ্রেণি Fooনির্ভর করে Logger.GetInstance(), Fooকার্যকরভাবে গ্রাহকদের কাছ থেকে তার নির্ভরতাগুলি গোপন করে। এর অর্থ হ'ল আপনি Fooযদি এটির উত্সটি না পড়ে এবং এটি নির্ভর করে যে সত্যটি উন্মোচন না করে আপনি এটিকে পুরোপুরি বুঝতে বা আত্মবিশ্বাসের সাথে ব্যবহার করতে পারবেন না Logger। যদি আপনার কাছে উত্স না থাকে, তবে আপনি যে কোডটি নির্ভর করছেন সেটিকে আপনি কতটা ভালভাবে বুঝতে এবং কার্যকরভাবে ব্যবহার করতে পারবেন তা সীমাবদ্ধ করে।

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


9
@ ব্রায়ানওয়াটস যা কিছু বলেছে, সিঙ্গেলনগুলি এখনও একটি সাধারণ মাঝারি স্কেল অ্যাপ্লিকেশনটিতে আরও দ্রুত এবং কম ত্রুটির প্রবণ। সাধারনত আমার (কাস্টম) লগারের জন্য আমার একাধিক সম্ভাব্য বাস্তবায়ন নেই তাই ** আমার কেন প্রয়োজন হবে: ১. এর জন্য একটি ইন্টারফেস তৈরি করুন এবং প্রতিবারই আমাকে জনসাধারণের সদস্যদের যোগ / পরিবর্তন করতে হবে এটি পরিবর্তন করুন ২ বজায় রাখুন একটি ডিআই কনফিগারেশন ৩. গোটা সিস্টেমে এই ধরণের একক অবজেক্ট রয়েছে তা লুকান 4.. অকাল বিচ্ছিন্নতার কারণে উদ্বেগের কারণে নিজেকে একটি কঠোর কার্যকারিতার সাথে আবদ্ধ করুন।
উরি আব্রামসন

@ উরিআব্র্যামসন: মনে হচ্ছে আপনি পছন্দসই ট্রেড অফস সম্পর্কে ইতিমধ্যে সিদ্ধান্ত নিয়েছেন তাই আমি আপনাকে বোঝানোর চেষ্টা করব না।
ব্রায়ান ওয়াটস

@ ব্রায়ান ওয়াটস এর ঘটনাটি নয়, সম্ভবত আমার মন্তব্যটি কিছুটা কঠোর ছিল তবে আমি যে বক্তব্যটি উত্থাপন করেছি সে সম্পর্কে আপনার বক্তব্যটি কী শুনতে আমি সত্যই আগ্রহী তা ...
উরি আব্রামসন

4
@ উরিআব্র্যামসন: যথেষ্ট ফর্সা। আপনি কি কমপক্ষে সম্মত হন যে পরীক্ষার সময় বিচ্ছিন্নকরণের জন্য বাস্তবায়নের অদলবদল গুরুত্বপূর্ণ?
ব্রায়ান ওয়াটস

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

19

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

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

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

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


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

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

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

4
@ কিরিয়ু, ভুল অনুমানের জন্য দুঃখিত। আমি একটি ডাউনভোট এবং একটি মন্তব্য দেখেছি, তাই আমি বিন্দুগুলিকে সংযুক্ত করেছি - ভুল উপায়ে, যেমনটি দেখা যাচ্ছে :-( আমি কোনও ভিন্ন লগিং ফ্রেমওয়ার্কে স্যুইচ করার প্রয়োজন অনুভব করি নি, তবে আবারও, আমি বুঝতে পারি এটি একটি আইনী হতে পারে কিছু প্রকল্পে উদ্বেগ।
পিটার টারিক

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

9

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

  • পরীক্ষা করা শক্ত। মানে আমি কীভাবে নিশ্চিত করব যে লগারটি সঠিকভাবে কাজ করে।
  • সঙ্গে পরীক্ষা করা কঠিন। অর্থ যদি আমি লગરটি ব্যবহার করে এমন কোডটি পরীক্ষা করে দেখি তবে এটি আমার পরীক্ষার কেন্দ্রবিন্দু নয়, তবে এখনও আমার পরীক্ষার env লগারের সমর্থন করে তা নিশ্চিত করা দরকার
  • কখনও কখনও আপনি একটি সিঙ্গলটন চান না, তবে আরও নমনীয়

ডিআই আপনাকে আপনার নির্ভরশীল ক্লাসগুলির সহজ খরচ দেয় - কেবল এটি কনস্ট্রাক্টর অর্গগুলিতে রাখুন এবং পরীক্ষাটি এবং নির্মাণের নমনীয়তা দেওয়ার সময় সিস্টেমটি এটি আপনাকে সরবরাহ করে giving


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

2

নির্ভরতা ইনজেকশনের পরিবর্তে আপনার একবারে সিঙ্গলটন ব্যবহার করা উচিত কেবলমাত্র যদি সিঙ্গলটন কোনও অপরিবর্তনীয় মান, যেমন লিস্ট.এম্পটি বা এর মতো (অপরিবর্তনীয় তালিকা ধরে ধরে) প্রতিনিধিত্ব করে represents

সিঙ্গেলনের জন্য অন্ত্রের চেকটি হওয়া উচিত "আমি কী ঠিক আছি যদি এটি একটি সিঙ্গেলনের পরিবর্তে বৈশ্বিক চলক হত?" যদি তা না হয় তবে আপনি বিশ্বব্যাপী ভেরিয়েবলের জন্য কাগজপত্রের জন্য সিঙ্গলটন প্যাটার্নটি ব্যবহার করছেন এবং এটির ভিন্ন পদ্ধতির বিষয়টি বিবেচনা করা উচিত।


1

স্রেফ মনসেটেট নিবন্ধটি পরীক্ষা করে দেখুন - এটি সিঙ্গলটনের একটি নিফটি বিকল্প, তবে এর কয়েকটি বিভক্ত বৈশিষ্ট্য রয়েছে:

class Mono{
    public static $db;
    public function setDb($db){
       self::$db = $db;
    }

}

class Mapper extends Mono{
    //mapping procedure
    return $Entity;

    public function save($Entity);//requires database connection to be set
}

class Entity{
public function save(){
    $Mapper = new Mapper();
    $Mapper->save($this);//has same static reference to database class     
}

$Mapper = new Mapper();
$Mapper->setDb($db);

$User = $Mapper->find(1);
$User->save();

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


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