কারও কারও মতে সিঙ্গলটন প্যাটার্ন সর্বদা একটি অ্যান্টি-প্যাটার্ন। আপনি কি মনে করেন?
কারও কারও মতে সিঙ্গলটন প্যাটার্ন সর্বদা একটি অ্যান্টি-প্যাটার্ন। আপনি কি মনে করেন?
উত্তর:
সিঙ্গেলটনের দুটি প্রধান সমালোচনা আমি যা দেখেছি তার থেকে দুটি শিবিরে পড়ে:
এই উভয়ের ফলস্বরূপ, একটি সাধারণ পদ্ধতির মধ্যে এই শ্রেণীর একক উদাহরণ ধরে রাখতে একটি বিস্তৃত ধারক অবজেক্ট তৈরি করা ব্যবহার করা হয় এবং কেবলমাত্র ধারক বস্তু এই ধরণের শ্রেণিগুলিকে সংশোধন করে এবং অন্যান্য ক্লাস থেকে তাদের ব্যবহারের জন্য অ্যাক্সেস দেওয়া যেতে পারে use ধারক বস্তু।
আমি একমত যে এটি একটি বিরোধী-নিদর্শন। কেন? কারণ এটি আপনার কোডকে তার নির্ভরতাগুলি সম্পর্কে মিথ্যাচারের অনুমতি দেয় এবং আপনি অন্যান্য প্রোগ্রামারগুলিকে আপনার পূর্ববর্তী অপরিবর্তনীয় একক সিলেটে পরিবর্তনযোগ্য অবস্থা প্রবর্তন করতে বিশ্বাস করতে পারবেন না।
কোনও শ্রেণীর একটি কনস্ট্রাক্টর থাকতে পারে যা কেবল স্ট্রিং নেয়, তাই আপনি মনে করেন এটি বিচ্ছিন্নভাবে ইনস্ট্যান্টেটেড এবং এর কোনও পার্শ্ব প্রতিক্রিয়া নেই। তবে, নিঃশব্দে, এটি কিছু ধরণের পাবলিক, বিশ্বব্যাপী উপলভ্য সিঙ্গলটন অবজেক্টের সাথে যোগাযোগ করছে, যাতে আপনি যখনই ক্লাসটি ইনস্ট্যান্ট করেন, এতে আলাদা আলাদা ডেটা থাকে। এটি আপনার এপিআই-র ব্যবহারকারীদের জন্যই নয়, কোডের পরীক্ষাযোগ্যতার জন্যও এটি একটি বড় সমস্যা। কোডটি যথাযথভাবে ইউনিট-টেস্ট করার জন্য, আপনাকে ধারাবাহিকভাবে পরীক্ষার ফলাফল পেতে, মাইক্রো-ম্যানেজ করতে হবে এবং একক মধ্যে বিশ্বব্যাপী রাষ্ট্র সম্পর্কে সচেতন হতে হবে।
সিঙ্গলটন প্যাটার্নটি মূলত কেবলমাত্র একটি অলসভাবে প্রাথমিক গ্লোবাল ভেরিয়েবল। গ্লোবাল ভেরিয়েবলগুলি সাধারণত এবং যথাযথভাবে মন্দ হিসাবে বিবেচিত হয় কারণ তারা কোনও প্রোগ্রামের আপাতদৃষ্টিতে সম্পর্কিত নয় এমন অংশগুলির মধ্যে একটি দূরত্বে স্পোকি ক্রিয়ার অনুমতি দেয়। তবে আইএমএইচও গ্লোবাল ভেরিয়েবলগুলির মধ্যে কোনও ভুল নেই যা একবারে একটি প্রোগ্রামের সূচনা রুটিনের অংশ হিসাবে (উদাহরণস্বরূপ, কোনও কনফিগার ফাইল বা কমান্ড লাইন আর্গুমেন্ট পড়ে) এবং তারপরে স্থির হিসাবে বিবেচিত হয় place সংকলন সময়ে নাম ধ্রুবক ঘোষণা করা থেকে বিশ্বব্যাপী ভেরিয়েবলের এ জাতীয় ব্যবহার কেবলমাত্র চিঠিতেই আলাদা spirit
একইভাবে, সিঙ্গেলটনের আমার মতামতটি যদি তারা কোনও প্রোগ্রামের আপাতদৃষ্টির সাথে সম্পর্কযুক্ত অংশের মধ্যে পারস্পরিক পরিবর্তন স্থিত করতে ব্যবহৃত হয় তবেই তারা খারাপ। যদি সেগুলিতে পরিবর্তনীয় স্থিতি না থাকে, বা যদি তারা যে পরিবর্তনীয় স্থিতিগুলি রাখে তা সম্পূর্ণরূপে এনক্যাপসুলেটেড হয় যাতে বস্তুর ব্যবহারকারীরা এমনকি এটি একটি বহু-বিস্তৃত পরিবেশেও জানতে না পারে, তবে তাদের সাথে কোনও ভুল নেই।
আমি পিএইচপি ওয়ার্ল্ডে বেশ কয়েকটি সিলেটলেট দেখেছি। প্যাটার্নটি ন্যায়সঙ্গত বলে প্রমাণ পেয়েছি এমন কোনও ব্যবহারের ঘটনা আমার মনে নেই। তবে আমি মনে করি লোকেরা কেন এটি অনুপ্রেরণা জাগিয়ে তোলে সে সম্পর্কে আমার ধারণা পেয়েছে।
একক উদাহরণ ।
"অ্যাপ্লিকেশন জুড়ে ক্লাস সি এর একক উদাহরণ ব্যবহার করুন" "
এটি একটি যুক্তিসঙ্গত প্রয়োজন যেমন "ডিফল্ট ডাটাবেস সংযোগ" এর জন্য। এর অর্থ এই নয় যে আপনি কখনই দ্বিতীয় ডিবি সংযোগ তৈরি করতে পারবেন না, এর অর্থ হ'ল আপনি সাধারণত ডিফল্ট সাথে কাজ করেন।
একক তাত্ক্ষণিক ।
"ক্লাস সি একাধিকবার ইনস্ট্যান্ট করার অনুমতি দেবেন না (প্রতিটি প্রক্রিয়া, প্রতি অনুরোধ, ইত্যাদি)"
এটি কেবল তখনই প্রাসঙ্গিক হয় যখন ক্লাসটি ইনস্ট্যান্ট করার সাথে সাথে পার্শ্ব প্রতিক্রিয়া হবে যা অন্যান্য দৃষ্টান্তের সাথে সাংঘর্ষিক।
প্রায়শই এই দ্বন্দ্বগুলি উপাদানটিকে নতুনভাবে ডিজাইন করে এড়ানো যেতে পারে - যেমন শ্রেণি নির্মাতা থেকে পার্শ্ব প্রতিক্রিয়াগুলি সরিয়ে দিয়ে। অথবা এগুলি অন্য উপায়ে সমাধান করা যেতে পারে। তবে এখনও কিছু আইনী ব্যবহারের মামলা থাকতে পারে।
"একমাত্র" প্রয়োজনের সত্যিকার অর্থে "প্রক্রিয়া অনুসারে একটি" কিনা তাও আপনার চিন্তা করা উচিত। উদাহরণস্বরূপ, সংস্থান সংক্রান্ত সামগ্রীর জন্য প্রয়োজনীয়তাটি "প্রক্রিয়া জুড়ে পুরো সিস্টেমের জন্য একটি" এবং "প্রক্রিয়া অনুসারে একটি" নয়। এবং অন্যান্য জিনিসের জন্য এটি "অ্যাপ্লিকেশন প্রসঙ্গ" অনুসারে হয় এবং প্রক্রিয়া অনুযায়ী আপনার কেবলমাত্র একটি অ্যাপ্লিকেশন প্রসঙ্গ থাকতে পারে।
অন্যথায়, এই ধারণাটি প্রয়োগ করার দরকার নেই। এটি প্রয়োগ করার অর্থ আপনি ইউনিট পরীক্ষার জন্য পৃথক উদাহরণ তৈরি করতে পারবেন না।
গ্লোবাল অ্যাক্সেস।
এটি কেবল তখনই বৈধ হয় যখন আপনার কাছে অবজেক্টগুলি যে স্থানে ব্যবহৃত হয় তার আশেপাশে কোনও উপযুক্ত অবকাঠামো না থাকে। এর অর্থ এই হতে পারে যে আপনার কাঠামো বা পরিবেশটি সফল হয় তবে এটি ঠিক করার পক্ষে এটি আপনার ক্ষমতার মধ্যে নাও থাকতে পারে।
দামটি কঠোর সংশ্লেষ, লুকানো নির্ভরতা এবং বিশ্বব্যাপী অবস্থার জন্য খারাপ যা কিছু। তবে আপনি সম্ভবত ইতিমধ্যে এগুলি ভুগছেন।
অলস তাত্পর্য।
এটি কোনও সিঙ্গলটনের প্রয়োজনীয় অংশ নয়, তবে এগুলি কার্যকর করার সবচেয়ে জনপ্রিয় উপায় বলে মনে হয়। তবে, অলস তাত্ক্ষণিকতা রাখা একটি দুর্দান্ত জিনিস, এটি অর্জনের জন্য আপনার সত্যিকার অর্থে সিঙ্গলটনের দরকার নেই।
সাধারণ প্রয়োগটি একটি প্রাইভেট কনস্ট্রাক্টর, এবং একটি স্ট্যাটিক দৃষ্টান্ত পরিবর্তনশীল এবং অলস তাত্ক্ষণিকতার সাথে একটি স্ট্যাটিক getInstance () পদ্ধতি সহ একটি বর্গ।
উপরে উল্লিখিত সমস্যাগুলি ছাড়াও, এটি একক দায়বদ্ধতার নীতির সাথে কামড়ায় , কারণ শ্রেণিটি ইতিমধ্যে স্বতন্ত্র দায়বদ্ধতা এবং জীবনচক্রকে নিয়ন্ত্রণ করে যা ক্লাসটি ইতিমধ্যে অন্যান্য দায়বদ্ধতার পাশাপাশি রয়েছে।
অনেক ক্ষেত্রে আপনি একই ফলাফলটি সিঙ্গলটন ছাড়াই এবং বৈশ্বিক রাষ্ট্র ব্যতীত অর্জন করতে পারেন। পরিবর্তে, আপনার নির্ভরতা ইনজেকশন ব্যবহার করা উচিত এবং আপনি নির্ভরতা ইনজেকশন ধারক বিবেচনা করতে চাইতে পারেন ।
তবে, এমন কিছু ব্যবহার রয়েছে যেখানে আপনার নিম্নলিখিত বৈধ প্রয়োজনীয়তাগুলি রয়েছেন:
সুতরাং, এই ক্ষেত্রে আপনি যা করতে পারেন তা এখানে:
একটি সার্বজনীন সি তৈরি করুন যা আপনি পাবলিক কনস্ট্রাক্টর সহ ইনস্ট্যান্ট করতে চান।
একটি অলস তাত্পর্য সহ একটি স্ট্যাটিক উদাহরণ ভেরিয়েবল এবং একটি স্ট্যাটিক এস :: getInstance () পদ্ধতি সহ একটি পৃথক ক্লাস এস তৈরি করুন, এটি উদাহরণস্বরূপ সি শ্রেণি ব্যবহার করবে।
সি এর কনস্ট্রাক্টর থেকে সমস্ত পার্শ্ব প্রতিক্রিয়া বাদ দিন পরিবর্তে এস পার্শ্ব প্রতিক্রিয়াগুলি S :: getInstance () পদ্ধতিতে রাখুন।
উপরোক্ত প্রয়োজনীয়তাগুলির সাথে যদি আপনার একাধিক শ্রেণি থাকে তবে আপনি একটি ছোট স্থানীয় পরিষেবা পাত্রে ক্লাসের উদাহরণগুলি পরিচালনা করতে বিবেচনা করতে পারেন এবং কেবল ধারক হিসাবে স্থির দৃষ্টান্তটি ব্যবহার করতে পারেন। সুতরাং, এস :: getContainer () আপনাকে একটি অলস-তাত্ক্ষণিক পরিষেবা কনটেইনার দেবে এবং আপনি অন্য ধারকটি ধারক থেকে পাবেন।
আপনি যেখানে পারেন সেখানে স্থিতিশীল getInstance () কল করা এড়িয়ে চলুন। পরিবর্তে যখনই সম্ভব নির্ভরতা ইনজেকশন ব্যবহার করুন। বিশেষত, আপনি যদি একে অপরের উপর নির্ভর করে এমন একাধিক অবজেক্টের সাথে ধারক পদ্ধতির ব্যবহার করেন তবে এগুলির কোনওটিকেই এস :: গেটকন্টেইনার () কল করতে হবে না।
ক্লাস সি প্রয়োগ করে interfaceচ্ছিকভাবে একটি ইন্টারফেস তৈরি করুন এবং এস :: getInstance () এর রিটার্ন মান ডকুমেন্ট করতে এটি ব্যবহার করুন।
(আমরা কি এখনও এটি সিঙ্গলটন বলি? আমি এটি মন্তব্য বিভাগে রেখে যাই))
উপকারিতা:
আপনি কোনও বৈশ্বিক রাজ্যের স্পর্শ না করে ইউনিট পরীক্ষার জন্য সি এর পৃথক উদাহরণ তৈরি করতে পারেন।
ইনস্ট্যান্স ম্যানেজমেন্ট ক্লাস থেকে নিজেই আলাদা হয় -> উদ্বেগের বিচ্ছেদ, একক দায়িত্বের নীতি।
উদাহরণস্বরূপ এস :: getInstance () কে আলাদা ক্লাস ব্যবহার করতে দেওয়া বা কোন শ্রেণীটি ব্যবহার করতে হবে তা গতিশীলভাবে নির্ধারণ করা বেশ সহজ হবে।
ব্যক্তিগতভাবে আমি যখন 1, 2, বা 3, বা প্রশ্নে নির্দিষ্ট শ্রেণীর জন্য কিছু সীমিত পরিমাণের অবজেক্টের প্রয়োজন হবে তখন আমি সিলেটলেট ব্যবহার করব। বা আমি আমার ক্লাসের ব্যবহারকারীর কাছে জানাতে চাই যে আমি চাই না যে আমার ক্লাসের একাধিক উদাহরণ তৈরি করা হয়েছে যাতে এটি সঠিকভাবে কাজ করে।
এছাড়াও আমি কেবল তখনই এটি ব্যবহার করব যখন আমার কোডের প্রায় সর্বত্র এটি ব্যবহার করতে হবে এবং আমি প্রতিটি শ্রেণি বা ক্রিয়াকলাপের জন্য প্রয়োজনীয় যে কোনও পরামিতি হিসাবে কোনও বস্তুটি পাস করতে চাই না।
এছাড়াও আমি কেবলমাত্র একটি সিঙ্গলটন ব্যবহার করব যদি এটি অন্য ফাংশনের রেফারেন্সিয়াল স্বচ্ছতা ভঙ্গ করে না। কিছু ইনপুট দেওয়া অর্থ এটি সর্বদা একই আউটপুট উত্পাদন করে। অর্থাৎ আমি এটি বিশ্বব্যাপী অবস্থার জন্য ব্যবহার করি না। যতক্ষণ না সম্ভব যে বিশ্বব্যাপী রাষ্ট্র একবার আরম্ভ করা হয় এবং কখনও পরিবর্তন হয় না।
কখন এটি ব্যবহার করবেন না, উপরের 3 টি দেখুন এবং তাদের বিপরীতে পরিবর্তন করুন।