তাই সিঙ্গলেটন খারাপ, তাহলে কী?


553

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

আমি জড়িত একটি বড় সাম্প্রতিক প্রকল্পের একটি বাস্তব উদাহরণ এখানে:

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

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


10
কোন একক ব্যবহারের সমাধান করার কথা? বিকল্পগুলির (যেমন একটি স্ট্যাটিক বর্গ) চেয়ে সমস্যাটি সমাধান করা কীভাবে ভাল?
আনন

14
@ অ্যান: স্ট্যাটিক ক্লাস ব্যবহার করে পরিস্থিতি আরও কীভাবে উন্নত হয়। এখনও টাইট কাপলিং আছে?
মার্টিন ইয়র্ক

5
@ মার্টিন: আমি প্রস্তাব দিচ্ছি না এটি এটিকে "আরও ভাল" করে তোলে। আমি পরামর্শ দিচ্ছি যে বেশিরভাগ ক্ষেত্রেই সিঙ্গেলটন হ'ল সমস্যার সন্ধানের সমাধান।
আনন

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

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

উত্তর:


809

একক দৃষ্টান্ত এবং সিঙ্গলটন ডিজাইন প্যাটার্নের মধ্যে পার্থক্য করা এখানে গুরুত্বপূর্ণ ।

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

সিঙ্গেলটন ডিজাইনের প্যাটার্নটি খুব নির্দিষ্ট ধরণের একক উদাহরণ, বিশেষত একটি:

  • বিশ্বব্যাপী, স্থির উদাহরণ ক্ষেত্রের মাধ্যমে অ্যাক্সেসযোগ্য;
  • হয় প্রোগ্রাম সূচনা বা প্রথম অ্যাক্সেস উপর তৈরি;
  • কোনও পাবলিক কনস্ট্রাক্টর (সরাসরি ইনস্ট্যান্ট করতে পারে না);
  • কখনই স্পষ্টভাবে মুক্তি দেওয়া হয়নি (প্রোগ্রাম সমাপ্তির ক্ষেত্রে স্পষ্টতই মুক্তি দেওয়া)।

এই নির্দিষ্ট নকশার পছন্দের কারণেই প্যাটার্নটি বেশ কয়েকটি সম্ভাব্য দীর্ঘমেয়াদী সমস্যার পরিচয় দেয়:

  • বিমূর্ত বা ইন্টারফেস ক্লাস ব্যবহারে অক্ষমতা;
  • সাবক্লাসে অক্ষমতা;
  • অ্যাপ্লিকেশন জুড়ে উচ্চ সংযুক্তকরণ (সংশোধন করা কঠিন);
  • পরীক্ষা করা কঠিন (ইউনিট পরীক্ষায় জাল / উপহাস করতে পারবেন না);
  • পরিবর্তনীয় অবস্থার ক্ষেত্রে সমান্তরাল হওয়া কঠিন (ব্যাপক লকিং প্রয়োজন);
  • ইত্যাদি।

এই লক্ষণগুলির কোনওটিই কেবল একক দৃষ্টান্তের জন্য স্থানীয় নয়, কেবলমাত্র সিঙ্গলটন প্যাটার্ন।

পরিবর্তে আপনি কি করতে পারেন? কেবল সিঙ্গলটন প্যাটার্ন ব্যবহার করবেন না।

প্রশ্ন থেকে উদ্ধৃতি:

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

এই ধারণার একটি নাম রয়েছে, আপনি যেমন ইঙ্গিত সাজান তেমন তবে অনিশ্চিত sound একে ক্যাশে বলা হয় । আপনি অভিনবতা পেতে চাইলে এটিকে একটি "অফলাইন ক্যাশে" বা দূরবর্তী ডেটার কেবল একটি অফলাইন অনুলিপি বলতে পারেন।

একটি ক্যাশে সিঙ্গলটন হওয়ার দরকার নেই। এটা তোলে পারে একটি একক উদাহরণস্বরূপ হতে হবে যদি আপনি একাধিক ক্যাশে দৃষ্টান্ত জন্য একই ডেটা আনার এড়াতে চান; তবে এর অর্থ এই নয় যে আপনাকে আসলে সকলের কাছে প্রকাশ করতে হবে

আমি প্রথমে যা করব তা হ'ল ক্যাশের বিভিন্ন কার্যকরী অঞ্চলকে আলাদা ইন্টারফেসে আলাদা করা separate উদাহরণস্বরূপ, ধরা যাক আপনি মাইক্রোসফ্ট অ্যাক্সেসের ভিত্তিতে বিশ্বের সবচেয়ে খারাপ ইউটিউব ক্লোন তৈরি করছিলেন:

                          MSAccessCache
                                ▲
                                |
              + + ----------------- + + ----------------- + +
              | | |
         IMediaCache IProfileCache IPageCache
              | | |
              | | |
          ভিডিওপেজ মাই অ্যাকাউন্টসপেজ মোস্টপোপুলারপেজ

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

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

আপনার ইন্টারফেস ভিত্তিক নকশা কেন ব্যবহার করা উচিত? তিনটি কারণ:

  1. কোডটি পড়া সহজ করে তোলে; নির্ভরযোগ্য ক্লাসগুলি কী ডেটা নির্ভর করে ঠিক সেই ইন্টারফেসগুলি থেকে আপনি স্পষ্টভাবে বুঝতে পারবেন ।

  2. যদি এবং আপনি যখন বুঝতে পারেন যে মাইক্রোসফ্ট অ্যাক্সেস কোনও ডেটা ব্যাক-এন্ডের জন্য সেরা পছন্দ নয় তবে আপনি এটিকে আরও ভাল কিছু দিয়ে প্রতিস্থাপন করতে পারেন - আসুন এসকিউএল সার্ভার বলি।

  3. যদি এবং আপনি যখন বুঝতে পারেন যে এসকিউএল সার্ভার বিশেষত মিডিয়াগুলির জন্য সেরা পছন্দ নয় , তবে আপনি সিস্টেমের অন্য কোনও অংশকে প্রভাবিত না করেই আপনার প্রয়োগটি ভেঙে ফেলতে পারেন । এখানেই বিমূর্তির আসল শক্তি আসে।

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

সম্পূর্ণতার স্বার্থে, আমার উল্লেখ করা উচিত যে উপরের নকশাটি সত্যই আদর্শ নয়। আপনি যখন ক্যাশের সাথে ডিল করছেন (যেমন আপনি আছেন) আপনার আসলে একটি সম্পূর্ণ পৃথক স্তর থাকা উচিত । অন্য কথায়, এটির মতো একটি নকশা:

                                                        - IMediaRepository
                                                        |
                          ক্যাশে (জেনেরিক) --------------- + - আইফ্রোফিলারপোসিটোরি
                                ▲ |
                                | - IPageRepository
              + + ----------------- + + ----------------- + +
              | | |
         IMediaCache IProfileCache IPageCache
              | | |
              | | |
          ভিডিওপেজ মাই অ্যাকাউন্টসপেজ মোস্টপোপুলারপেজ

এর সুবিধাটি হ'ল আপনি Cacheযদি পুনরুদ্ধার করার সিদ্ধান্ত নেন তবে আপনার উদাহরণটি কখনও ভাঙতে হবে না ; আপনি কীভাবে মিডিয়াটিকে বিকল্প বিকল্প প্রয়োগ করে খাওয়ানোর মাধ্যমে তা সংরক্ষণ করা যায় তা আপনি পরিবর্তন করতে পারবেন IMediaRepository। এটি কীভাবে একসাথে খাপ খায় সে সম্পর্কে আপনি যদি ভাবেন তবে আপনি দেখতে পাবেন এটি এখনও কেবলমাত্র ক্যাশের একটি শারীরিক উদাহরণ তৈরি করে, তাই আপনার কখনও কখনও একই ডেটা আনার দরকার নেই।

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

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


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

4
কেন ক্যাশে সিঙ্গলটন হতে পারে না? আপনি যদি এটি পাস করে এবং নির্ভরতা ইনজেকশন ব্যবহার করেন তবে এটি কি সিঙ্গলটন নয়? সিঙ্গেলটন কেবলমাত্র একটি উদাহরণে নিজেকে সীমাবদ্ধ করার বিষয়ে, এটি কীভাবে সঠিকভাবে অ্যাক্সেস করা যায় তা সম্পর্কে নয়? : এই আমার নিন দেখুন assoc.tumblr.com/post/51302471844/the-misunderstood-singleton
এরিক Engheim

29
@AdamSmith: আপনি আসলে পড়তে হয়নি কোনো এই উত্তর? আপনার প্রশ্নের উত্তর প্রথম দুটি অনুচ্ছেদে দেওয়া হয়েছে। একক প্যাটার্ন! == একক দৃষ্টান্ত।
অ্যারোনআউট

5
@ কাওস এবং অ্যাডাম স্মিথ - আপনার লিঙ্কগুলি পড়ে আমার মনে হয় যে আপনি এই উত্তরটি সত্যিই পড়েন নি - সবকিছু ইতিমধ্যে রয়েছে already
উইলবার্ট

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

48

আপনি যে ক্ষেত্রে দেন, মনে হয় একা সিঙ্গলটনের ব্যবহার সমস্যা নয়, তবে সমস্যার লক্ষণ - একটি বৃহত্তর, স্থাপত্য সমস্যা problem

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

সমস্যাটি সম্ভবত সিস্টেমের অংশগুলির মধ্যে নির্ভরতা সঠিকভাবে সেট আপ করা হয়নি এবং এটি সম্ভবত সিস্টেমিক।

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

আবার, আমরা বড় আকারের আর্কিটেকচারাল এবং ডিজাইনের সমস্যাগুলি দেখছি।

এছাড়াও, এটি বুঝতে খুব গুরুত্বপূর্ণ যে কোনও বস্তুর ব্যবহারের জন্য কীভাবে খুঁজে পাওয়া যায় তার থেকে কোনও সামগ্রীর জীবনকাল পুরোপুরি ডিভোর্স হতে পারে।

কোনও ক্যাশে অ্যাপ্লিকেশনটির সারা জীবন জুড়ে বাঁচতে হবে (দরকারী হতে), যাতে সেই বস্তুর আজীবন কোনও একক সিলেটের জীবনযাপন।

তবে সিঙ্গলটনের সমস্যা (কমপক্ষে একক স্ট্যাটিক শ্রেণি / সম্পত্তি হিসাবে সিঙ্গেলনের সাধারণ প্রয়োগ), এটি ব্যবহার করা অন্যান্য শ্রেণিগুলি এটি সন্ধান করার ক্ষেত্রে কীভাবে চলে।

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

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


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

1
<কন্টেন্ট> এটি মূলত স্বচ্ছ। এই অর্থে যে কিছু প্রয়োজনীয় ডেটা এখনও ক্যাশ না করা থাকলে সার্ভার থেকে একটি কলব্যাক রয়েছে। কিন্তু সেই ক্যাশে পরিচালকের বাস্তবায়ন (যৌক্তিক ও শারীরিকভাবে) একজন সিঙ্গলটন।
ববি টেবিলগুলি 0

6
আমি এখানে কাস্টারিনের সাথে আছি: তথ্য অ্যাক্সেসকারী অবজেক্টগুলিকে (বা এটি জানা দরকার) ডেটা ক্যাশে করা উচিত নয় (এটি বাস্তবায়নের বিশদ)। ডেটা ব্যবহারকারীরা কেবল ডেটা চায় (বা ডেটা পুনরুদ্ধারের জন্য ইন্টারফেসের জন্য জিজ্ঞাসা করে)।
মার্টিন ইয়র্ক

1
ক্যাচিং মূলত একটি বাস্তবায়ন বিশদ। একটি ইন্টারফেস রয়েছে যার মাধ্যমে ডেটা অনুসন্ধান করা হয় এবং এটি প্রাপ্ত বস্তুগুলি জানে না এটি ক্যাশে থেকে এসেছে কি না। তবে এই ক্যাশে ম্যানেজারটির নীচে একটি সিঙ্গলটন।
ববি টেবিলগুলি

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

45

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

TL; ড:

গ্যাং অফ ফোর সিঙ্গলটন প্যাটার্ন দুটি কাজ করে: আপনাকে যে কোনও জায়গা থেকে কোনও অ্যাক্সেসের সুবিধার্থে অ্যাক্সেস দেয় এবং নিশ্চিত করে নিন যে এর কেবলমাত্র একটি উদাহরণ তৈরি করা যেতে পারে। 99% সময়, আপনি যে বিষয়টির যত্ন নেন তা হ'ল প্রথমার্ধ এবং দ্বিতীয়ার্ধে কার্টিংয়ের জন্য এটি অপ্রয়োজনীয় সীমাবদ্ধতা যুক্ত করে।

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

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

  • এটি পুরোপুরি খনন করুন। আমি প্রচুর সিঙ্গলটন ক্লাস দেখেছি যার কোনও রাজ্য নেই এবং কেবল সহায়ক ফাংশনগুলির ব্যাগ। তাদের মোটেই উদাহরণের দরকার নেই। কেবল তাদের স্থির ফাংশন তৈরি করুন, বা এটিকে যুক্তি হিসাবে ফাংশনটি গ্রহণ করে এমন কোনও শ্রেণিতে সরিয়ে দিন। আপনি Mathঠিক করতে পারলে আপনার কোনও বিশেষ শ্রেণির প্রয়োজন হবে না 123.Abs()

  • এটি চারপাশে পাস। কোনও পদ্ধতির জন্য যদি অন্য কোনও অবজেক্টের প্রয়োজন হয় তবে এর সহজ সমাধানটি কেবল এটি প্রবেশ করানো some কিছু কিছু বস্তুর চারপাশে পাস করার সাথে কোনও দোষ নেই।

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


1
আপনি এখানে সংক্ষিপ্ত করতে পারেন?
নিকোল

1
সম্পন্ন হয়েছে তবে আমি এখনও আপনাকে পুরো অধ্যায়টি পড়তে উত্সাহিত করেছি।
উপুড়হস্ত

4
অন্য বিকল্প: নির্ভরতা ইনজেকশন!
ব্র্যাড কাপিট

1
@ ব্র্যাডকুপিট তিনি এই লিঙ্কটিতেও সে সম্পর্কে কথা বলেছেন ... আমার অবশ্যই বলতে হবে যে আমি এখনও সবগুলি হজম করার চেষ্টা করছি। তবে এটি আমি এখনও পড়েছি এমন একক পাঠকগুলিতে সর্বাধিক বর্ণনামূলক পাঠযোগ্য। এখন পর্যন্ত আপনি, আমি ইতিবাচক singletons প্রয়োজন ছিল, শুধু বিশ্বব্যাপী Vars মত ছিল, এবং আমি প্রচার টুলবক্স । এখন আমি আর জানি না। মিঃ মুনিফিয়িয়েন্ট আপনি কি আমাকে বলতে পারবেন যে সার্ভিস লোকেটারটি কেবল একটি স্ট্যাটিক টুলবক্স ? এটিকে একটি সিঙ্গলটন (এভাবে একটি সরঞ্জামবাক্স) তৈরি করা কি ভাল হবে না?
ক্রেগক্স

1
"সরঞ্জামবাক্স" আমার কাছে "সার্ভিস লোকেটার" এর মতো দেখতে বেশ অনুরূপ। আপনি এটির জন্য কোনও স্ট্যাটিক ব্যবহার করেন না, বা এটি নিজেকে সিঙ্গলটন হিসাবে তৈরি করেন না কেন, আমি মনে করি, বেশিরভাগ প্রোগ্রামের জন্য এটি অতটা গুরুত্বপূর্ণ নয়। আমি স্ট্যাটিকসের দিকে ঝুঁকে পড়েছি কারণ অলস প্রারম্ভিককরণ এবং গাদা বরাদ্দের সাথে কেন চুক্তি করতে হবে না?
উপুড়হস্ত

21

এটি প্রতি বিশ্বব্যাপী রাষ্ট্র নয় যে সমস্যা।

সত্যিই আপনার কেবল উদ্বিগ্ন হওয়া দরকার global mutable state। ধ্রুবক রাষ্ট্র পার্শ্ব প্রতিক্রিয়া দ্বারা প্রভাবিত হয় না এবং এইভাবে সমস্যা কম হয়।

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

আপনার পরিস্থিতিতে আমি মনে করি যতক্ষণ না আপনার সিঙ্গলটন প্রকৃতপক্ষে কোনও ইন্টারফেস প্রয়োগ করে (যাতে অন্য পরিস্থিতিতে কোনও বিকল্প ব্যবহার করা যায়) ততক্ষণ আপনি এ থেকে দূরে সরে যেতে পারবেন।

তবে সিঙ্গেলনের সাথে ফিরে আসা আরও একটি বড় অঙ্কনটি হ'ল একবার তারা জায়গা থেকে পরে কোড থেকে তাদের সরিয়ে নিয়ে অন্য কিছু দিয়ে প্রতিস্থাপন করা একটি সত্যিকারের কঠিন কাজ হয়ে যায় (আবার সেই সংযোগটিও রয়েছে)।

// Example from 5 minutes (con't be too critical)
class ServerFactory
{
    public:
        // By default return a RealServer
        ServerInterface& getServer();

        // Set a non default server:
        void setServer(ServerInterface& server);
};

class ServerInterface { /* define Interface */ };

class RealServer: public ServerInterface {}; // This is a singleton (potentially)

class TestServer: public ServerInterface {}; // This need not be.

এটা বোধগম্য. এটি আমাকে ভাবতেও বাধ্য করে যে আমি কখনও সত্যই সিঙ্গলটনের অপব্যবহার করি নি, তবে কেবল সেগুলির কোনও ব্যবহারে সন্দেহ করা শুরু করি। তবে এই পয়েন্টগুলি অনুসারে আমি যে কোনও প্রকাশ্য অপব্যবহার করেছি তা ভাবতে পারি না। :)
ববি টেবিলগুলি

2
(আপনি সম্ভবত মানে কোনটাই "বলুন প্রতি" নয়)
nohat

4
@ নাহাত: আমি "কুইনস ইংলিশ" এর স্থানীয় বক্তা এবং এইভাবে ফরাসী ভাষায় কিছু না প্রত্যাশা করি যতক্ষণ না আমরা এটিকে আরও ভাল করে তুলি (যেমন le weekendউফ যেমন আমাদের অন্যতম)। ধন্যবাদ :-)
মার্টিন ইয়র্ক

21
প্রতি সে লাতিন।
আনন

2
@ অনন: ঠিক আছে এটি এতটা খারাপ নয় ;-)
মার্টিন ইয়র্ক

19

তারপর কি? যেহেতু কেউ এটি বলে নি: টুলবক্স । যে আপনি যদি চান গ্লোবাল ভেরিয়েবল

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

সহজ কথায় বলতে গেলে, অ্যাপ্লিকেশনটির সরঞ্জামবক্সটি একটি সিঙ্গলটন যা নিজেই কনফিগার করার জন্য বা অ্যাপ্লিকেশনটির সূচনা প্রক্রিয়াটিকে এটির কনফিগার করার অনুমতি দেওয়ার জন্য দায়ী ...

public class Toolbox {
     private static Toolbox _instance; 

     public static Toolbox Instance {
         get {
             if (_instance == null) {
                 _instance = new Toolbox(); 
             }
             return _instance; 
         }
     }

     protected Toolbox() {
         Initialize(); 
     }

     protected void Initialize() {
         // Your code here
     }

     private MyComponent _myComponent; 

     public MyComponent MyComponent() {
         get {
             return _myComponent(); 
         }
     }
     ... 

     // Optional: standard extension allowing
     // runtime registration of global objects. 
     private Map components; 

     public Object GetComponent (String componentName) {
         return components.Get(componentName); 
     }

     public void RegisterComponent(String componentName, Object component) 
     {
         components.Put(componentName, component); 
     }

     public void DeregisterComponent(String componentName) {
         components.Remove(componentName); 
     }

}

কিন্তু অনুমান করতে পার কি? এটা সিঙ্গলটন!

এবং একটি সিঙ্গলটন কি?

এখান থেকেই বিভ্রান্তি শুরু হয়।

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

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

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

আমাকে ভুল করবেন না!

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

যাইহোক, টুলবক্স ছাড়াও আরও অনেক পরামর্শ রয়েছে এবং টুলবক্সের মতোই প্রত্যেকেরই প্রয়োগ রয়েছে ...

অন্যান্য বিকল্প

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

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

উপরের দুটি বিকল্পই ভাল বিকল্প। তবে এটি আপনার ব্যবহারের উপর নির্ভর করে।

এখন, সংকেত বোঝানো সব খরচ এড়ানো উচিত কেবল ভুল ...

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

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

ব্যবহারিক উদাহরণ

আমি প্রায়শই 2 টি ব্যবহার করা দেখতে পাচ্ছি, উভয় পক্ষে এবং সিঙ্গেলনের বিপরীতে। ওয়েব ক্যাশে (আমার ক্ষেত্রে) এবং লগ ইন করুন সেবা

লগিং, কিছু যুক্তিযুক্ত হবে , একটি নিখুঁত একক উদাহরণ, কারণ, এবং আমি উদ্ধৃত:

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

অন্যরা যখন তর্ক করবে তখন লগ সার্ভিসটি প্রসারিত করা কঠিন হয়ে পড়ে যখন আপনি অবশেষে বুঝতে পারবেন যে এটি আসলে কেবল একটি উদাহরণ নয় should

ঠিক আছে, আমি বলি উভয় যুক্তিই বৈধ। এখানে সমস্যাটি আবার একক প্যাটার্নে নেই। এটি যদি স্থাপত্য সংক্রান্ত সিদ্ধান্ত এবং ওজন নিয়ে থাকে তবে যদি রিফ্যাক্টরিং একটি কার্যকর ঝুঁকি থাকে। এটি আরও সমস্যা হয় যখন, সাধারণত, রিফ্যাক্টরিং সর্বশেষ প্রয়োজন সংশোধনমূলক ব্যবস্থা measure


@ ধন্যবাদ ধন্যবাদ! আমি সিংগলটন ব্যবহার সম্পর্কে কিছু সতর্কতা যুক্ত করার জন্য উত্তরটি সম্পাদনা করার কথা ভাবছিলাম ... আপনার উক্তিটি পুরোপুরি ফিট করে!
ক্রেগক্স

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

@ হ্যাঁ, আমি জানতাম যে এটি দীর্ঘ যুদ্ধ। আমি আশা করি সময় বলবে। ;-)
ক্রেগোক্স

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

1
@ কাওস: আহ, দুঃখিত - এতে বিভ্রান্ত হয়ে পড়েছেন java.awt.Toolkit। আমার বক্তব্যটি একই তবে: Toolboxএকক উদ্দেশ্যযুক্ত সুসংগত শ্রেণীর চেয়ে বরং সম্পর্কিত নয় বিট এবং টুকরাগুলির গ্র্যাব-ব্যাগের মতো শোনাচ্ছে। আমার কাছে ভাল ডিজাইনের মতো শোনাচ্ছে না। (দ্রষ্টব্য যে আপনি নিবন্ধটি উল্লেখ করেছেন 2001 এর, নির্ভরতা ইনজেকশন এবং ডিআই কনটেইনারগুলি সাধারণ হয়ে উঠার আগে।)
জন স্কিটে

5

সিঙ্গলটন ডিজাইন প্যাটার্নটির সাথে আমার প্রধান সমস্যাটি হ'ল আপনার আবেদনের জন্য ভাল ইউনিট পরীক্ষাগুলি লেখা খুব কঠিন।

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

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

আপনি যদি নিজের অ্যাপ্লিকেশন তৈরির উপাদানগুলি কনফিগার করতে এবং ইনস্ট্যান্ট করতে আইওসি পাত্রে ব্যবহার করেন তবে আপনি সহজেই আপনার আইওসি পাত্রে "ম্যানেজার" এর একটি মাত্র উদাহরণ তৈরি করতে কনফিগার করতে পারেন, আপনাকে একই অর্জনের অনুমতি দেয়, কেবলমাত্র একটি উদাহরণ বৈশ্বিক অ্যাপ্লিকেশন ক্যাশে নিয়ন্ত্রণ করে ।

তবে আপনি যদি ইউনিট পরীক্ষাগুলি সম্পর্কে চিন্তা না করেন তবে একটি সিঙ্গলটন ডিজাইনের প্যাটার্নটি পুরোপুরি সূক্ষ্ম হতে পারে। (তবে আমি যাইহোক এটি করব না)


সুন্দরভাবে ব্যাখ্যা করা হয়েছে, এটিই উত্তর যা
সিঙ্গলেটনের

4

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

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

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

যখন একটি সিঙ্গলটন সত্যই সিঙ্গলটন না হয় (এটি যখন বেশিরভাগ প্রোগ্রামাররা বিচলিত হয়) তখন এটি একটি অলস তাত্ক্ষণিক গ্লোবাল, সঠিক উদাহরণটি ইনজেকশনের কোনও সুযোগ নেই।

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


3

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

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


2

সিঙ্গলেটগুলি হ'ল একটি প্রোগ্রামে কোনও সার্ভিস ভিত্তিক আর্কিটেকচারের অভিক্ষেপ মাত্র।

একটি এপিআই একটি প্রোটোকল স্তরে সিঙ্গলটনের উদাহরণ। মূলত সিলেটলেটগুলির মাধ্যমে আপনি টুইটার, গুগল ইত্যাদি অ্যাক্সেস করতে পারেন। তাহলে কেন একটি প্রোগ্রামের মধ্যে সিঙ্গেলনগুলি খারাপ হয়ে যায়?

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

সিঙ্গলেটগুলি একটি পরিষেবা অ্যাক্সেস পয়েন্ট। কার্যক্ষমতার একটি শক্তভাবে আবদ্ধ লাইব্রেরিতে পাবলিক ইন্টারফেস যা সম্ভবত খুব পরিশীলিত অভ্যন্তরীণ আর্কিটেকচারকে আড়াল করে।

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

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

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

কিছুটা এইরকম:

//XxxService.h:
/**
 * Provide singleton wrapper for Xxx object. This wrapper
 * can be autogenerated so is not made part of the object.
 */

#include "Xxx/Xxx.h"


class XxxService
{
    public:
    /**
     * Return a Xxx object as a singleton. The double check
     * singleton algorithm is used. A 0 return means there was
     * an error. Developers should use this as the access point to
     * get the Xxx object.
     *
     * <PRE>
     * @@ #include "Xxx/XxxService.h"
     * @@ Xxx* xxx= XxxService::Singleton();
     * <PRE>
     */

     static Xxx*     Singleton();

     private:
         static Mutex  mProtection;
};


//XxxService.cpp:

#include "Xxx/XxxService.h"                   // class implemented
#include "LockGuard.h"     

// CLASS SCOPE
//
Mutex XxxService::mProtection;

Xxx* XxxService::Singleton()
{
    static Xxx* singleton;  // the variable holding the singleton

    // First check to see if the singleton has been created.
    //
    if (singleton == 0)
    {
        // Block all but the first creator.
        //
        LockGuard lock(mProtection);

        // Check again just in case someone had created it
        // while we were blocked.
        //
        if (singleton == 0)
        {
            // Create the singleton Xxx object. It's assigned
            // to a temporary so other accessors don't see
            // the singleton as created before it really is.
            //
            Xxx* inprocess_singleton= new Xxx;

            // Move the singleton to state online so we know that is has
            // been created and it ready for use.
            //
            if (inprocess_singleton->MoveOnline())
            {
                LOG(0, "XxxService:Service: FAIL MoveOnline");
                return 0;
            }

            // Wait until the module says it's in online state.
            //
            if (inprocess_singleton->WaitTil(Module::MODULE_STATE_ONLINE))
            {
                LOG(0, "XxxService:Service: FAIL move to online");
                return 0;
            }

            // The singleton is created successfully so assign it.
            //
            singleton= inprocess_singleton;


        }// still not created
    }// not created

    // Return the created singleton.
    //
    return singleton;

}// Singleton  

1

প্রথম প্রশ্ন, আপনি কি অ্যাপ্লিকেশনটিতে অনেকগুলি বাগ খুঁজে পান? সম্ভবত ক্যাশে আপডেট করতে ভুলে গেছেন, বা খারাপ ক্যাশে বা এটি পরিবর্তন করা কঠিন? (আমি মনে করি কোনও অ্যাপ্লিকেশন আকার পরিবর্তন করতে পারে না যদি না আপনি রঙও পরিবর্তন করেন ... আপনি তবে রঙটি পরিবর্তন করতে এবং আকারটি রাখতে পারেন)।

আপনি যা করবেন তা হচ্ছে সেই শ্রেণিটি কিন্তু সমস্ত স্থিতি সদস্যদের সরান। ঠিক আছে এটি নেসেসারি নয় তবে আমি এটির প্রস্তাব দিই। সত্যিই আপনি কেবল ক্লাসটি একটি সাধারণ ক্লাসের মতো শুরু করেন এবং পয়েন্টারটি পাস করে দিন Class ক্লাসিওয়ান্ট.অ্যাপ্ট্র () লিখুন না। LetMeChange.ANYTHINGATALL ()। Andhave_no_st جوړ (()

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


1

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

গ্রাফিক:

DB
|
DB Accessor for OBJ A
| 
Cache for OBJ A
|
OBJ A Client requesting

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

এটি জিনিসগুলি ডিউপল করে যাতে আপনি কিছু উবার-ক্যাশে অবজেক্ট না করে নতুন ক্যাশে যুক্ত করতে পারেন। YMMV। IANAL। ইত্যাদি


1

পার্টিতে কিছুটা দেরি হলেও যাই হোক।

সিঙ্গলটন হ'ল একটি সরঞ্জাম বাক্সের একটি সরঞ্জাম, ঠিক অন্য কোনও কিছুর মতো। আশা করি আপনার সরঞ্জাম বাক্সে একটি মাত্র হাতুড়ির চেয়ে আরও বেশি কিছু রয়েছে।

এই বিবেচনা:

public void DoSomething()
{
    MySingleton.Instance.Work();
}

বনাম

public void DoSomething(MySingleton singleton)
{
    singleton.Work();
}
DoSomething(MySingleton.instance);

প্রথম ক্ষেত্রে উচ্চ মিলন ইত্যাদির দিকে নিয়ে যায়; ২ য় উপায়টিতে কোনও সমস্যা নেই @ অ্যারোনট বর্ণনা করছেন, যতদূর আমি বলতে পারি। আপনি এটি কীভাবে ব্যবহার করেন সে সম্পর্কে এটি সমস্ত।


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

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

1

প্রতিটি স্ক্রিন তাদের পরিচালক হিসাবে পরিচালক নিতে।

আপনি যখন আপনার অ্যাপ্লিকেশনটি শুরু করেন, আপনি ম্যানেজারটির একটি উদাহরণ তৈরি করেন এবং এটি চারপাশে পাস করেন।

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

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

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