জাভা এবং সি # এর মধ্যে একটি ছোট পার্থক্য রয়েছে যা এখানে প্রাসঙ্গিক। জাভাতে, প্রতিটি সদস্যই ডিফল্টরূপে ভার্চুয়াল। সি # তে, প্রতিটি সদস্যই পূর্বনির্ধারিতভাবে সিল করা হয় - ইন্টারফেস সদস্যদের ব্যতীত।
এই অনুমানগুলি যা গাইডলাইনটির উপর প্রভাব ফেলে - জাভাতে, প্রতিটি পাবলিক প্রকারকে লিসকোভের সাবস্টিটিউশন নীতিমালা [1] অনুসারে চূড়ান্তভাবে বিবেচনা করা উচিত। আপনার যদি কেবল একটি বাস্তবায়ন থাকে তবে আপনি শ্রেণীর নাম রাখবেন Parser
; যদি আপনি দেখতে পান যে আপনার একাধিক বাস্তবায়ন প্রয়োজন, আপনি কেবল ক্লাসটি একই নামের একটি ইন্টারফেসে পরিবর্তন করবেন এবং কংক্রিট বাস্তবায়নটির নাম বর্ণনামূলক কিছুতে রাখবেন।
সি # তে, মূল অনুমানটি হ'ল যখন আপনি কোনও ক্লাস পাবেন (নামটি শুরু হয় না I
), এটিই আপনি চান এমন শ্রেণি। মনে রাখবেন, এটি কোথাও 100% এর কাছাকাছি নেই - একটি সাধারণ পাল্টা উদাহরণের মতো ক্লাসগুলি হবে Stream
(যা সত্যই ইন্টারফেস বা একাধিক ইন্টারফেস হওয়া উচিত ছিল), এবং প্রত্যেকেরই নিজস্ব ভাষাগুলি এবং অন্যান্য ভাষাগুলির ব্যাকগ্রাউন্ড রয়েছে। Base
বিমূর্ত শ্রেণিকে বোঝাতে মোটামুটি বহুল ব্যবহৃত প্রত্যয়গুলির মতো অন্যান্য ব্যতিক্রমগুলিও রয়েছে - ঠিক একটি ইন্টারফেসের মতোই, আপনি জানেন যে টাইপটি বহুকোষী বলে ধারণা করা হচ্ছে।
কার্যকারিতার জন্য অ-আই-প্রিফিক্সড নামটি ছেড়ে দেওয়ার ক্ষেত্রে একটি দুর্দান্ত ব্যবহারযোগ্যতা বৈশিষ্ট্যও রয়েছে যা ইন্টারফেসটিকে একটি বিমূর্ত শ্রেণি তৈরি না করেই ইন্টারফেসের সাথে সম্পর্কিত which (যা সি # তে ক্লাসের একাধিক-উত্তরাধিকারের অভাবে ক্ষতিগ্রস্থ হবে)। এটি লিনকিউ দ্বারা জনপ্রিয় হয়েছিল, যা IEnumerable<T>
ইন্টারফেস Enumerable
হিসাবে এবং সেই ইন্টারফেসের জন্য প্রযোজ্য পদ্ধতিগুলির একটি সংগ্রহস্থল হিসাবে ব্যবহৃত হয়। এটি জাভাতে অপ্রয়োজনীয়, যেখানে ইন্টারফেসগুলিতে পদ্ধতি প্রয়োগকরণও থাকতে পারে।
শেষ পর্যন্ত, I
উপসর্গটি সি # বিশ্বে ব্যাপকভাবে ব্যবহৃত হয় এবং এক্সটেনশনের মাধ্যমে। নেট নেট (যেহেতু .NET কোডটি বেশিরভাগ ক্ষেত্রে সি # তে লিখিত হয়, বেশিরভাগ পাবলিক ইন্টারফেসের জন্য সি # নির্দেশিকা অনুসরণ করা বোধগম্য হয়)। এর অর্থ হল আপনি প্রায় অবশ্যই লাইব্রেরি এবং কোডটি নিয়ে কাজ করছেন যা এই স্বরলিপিটি অনুসরণ করে এবং অপ্রয়োজনীয় বিভ্রান্তি রোধ করার জন্য traditionতিহ্যটি গ্রহণ করা বোধগম্য - এটি উপসর্গটি বাদ দেওয়ার মতো নয় যা আপনার কোডকে আরও ভাল করে তুলবে :)
আমি ধরে নিয়েছি যে চাচা বব এর যুক্তি কিছু ছিল:
IBanana
কলার বিমূর্ত ধারণা। যদি এমন কোনও প্রয়োগকারী শ্রেণি থাকতে পারে যার চেয়ে ভাল নাম না থাকে Banana
তবে বিমূর্ততা সম্পূর্ণ অর্থহীন, এবং আপনার ইন্টারফেসটি ফেলে দেওয়া উচিত এবং কেবল একটি ক্লাস ব্যবহার করা উচিত। যদি আরও ভাল নাম (বলে, LongBanana
বা AppleBanana
) থাকে Banana
তবে ইন্টারফেসের নাম হিসাবে ব্যবহার না করার কোনও কারণ নেই । সুতরাং, I
উপসর্গটি ব্যবহার করে বোঝায় যে আপনার একটি অকেজো বিমূর্ততা রয়েছে, যা কোনও সুবিধা ছাড়াই কোডটি বোঝা আরও শক্ত করে তোলে। এবং যেহেতু কঠোর OOP আপনার কাছে সবসময় ইন্টারফেসের বিরুদ্ধে কোড রাখে, কেবলমাত্র এমন এক জায়গায় যেখানে আপনি I
কোনও টাইপের উপসর্গ দেখতে পাবেন না এটি একটি নির্মাতার উপর থাকবে - বেশ অর্থহীন শব্দ noise
আপনি যদি আপনার নমুনা IParser
ইন্টারফেসে এটি প্রয়োগ করেন তবে আপনি পরিষ্কারভাবে দেখতে পাবেন যে বিমূর্তিটি পুরোপুরি "অর্থহীন" অঞ্চলে রয়েছে। উভয় ক্ষেত্রেই একটা পার্সার (যেমন একটি কংক্রিট বাস্তবায়ন সম্পর্কে কিছু নির্দিষ্ট JsonParser
, XmlParser
, ...), অথবা আপনি শুধু একটি বর্গ ব্যবহার করা উচিত। "ডিফল্ট বাস্তবায়ন" বলে কোনও জিনিস নেই (যদিও কিছু পরিবেশে এটি সত্যই উপলব্ধি করে - উল্লেখযোগ্যভাবে, COM) হয় হয় একটি নির্দিষ্ট প্রয়োগ রয়েছে, বা আপনি "ডিফল্ট" এর জন্য একটি বিমূর্ত শ্রেণি বা এক্সটেনশন পদ্ধতি চান want তবে, সি # তে, যদি না আপনার কোডবেস ইতিমধ্যে I
প্রিফিক্স বাদ দেয় , রাখুন। আপনি যখনই কোডটি দেখতে পান class Something: ISomething
তখনই একটি মানসিক নোট তৈরি করুন - এর অর্থ কেউ YAGNI অনুসরণ এবং যুক্তিসঙ্গত বিমূর্ততা তৈরি করতে খুব ভাল নয়।
[1] - প্রযুক্তিগতভাবে লিসকভের কাগজে এটি নির্দিষ্টভাবে উল্লেখ করা হয়নি, তবে এটি মূল ওওপি পেপারের অন্যতম ভিত্তি এবং আমার লিসকভ পড়ার ক্ষেত্রে, তিনি এটিকে চ্যালেঞ্জ করেননি। কম কঠোর ব্যাখ্যায় (বেশিরভাগ ওওপি ভাষায় নেওয়া একটি), এর অর্থ এই যে জনসাধারণের ধরণের ব্যবহারের বিকল্প যা বিকল্পের জন্য উদ্দিষ্ট (যেমন চূড়ান্ত নয় / সিলযুক্ত) অবশ্যই সেই ধরণের যে কোনও কার্যকর প্রয়োগের সাথে কাজ করবে।