"যদি কোনও পদ্ধতি পরিবর্তন ছাড়াই পুনরায় ব্যবহার করা হয়, তবে পদ্ধতিটি একটি বেস শ্রেণিতে রাখুন, না হলে একটি ইন্টারফেস তৈরি করুন" একটি ভাল নিয়ম-এর থাম্ব?


10

আমার এক সহকর্মী বেস ক্লাস বা ইন্টারফেস তৈরির মধ্য থেকে চয়ন করার জন্য একটি নিয়ম-থাম্ব নিয়ে এসেছিলেন।

তিনি বলেন:

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

উদাহরণ স্বরূপ:

ক্লাসগুলি বিবেচনা করুন catএবং dog, যা ক্লাস প্রসারিত mammalএবং একটি পদ্ধতি আছে pet()। তারপরে আমরা ক্লাসটি যুক্ত করি alligator, যা কোনও কিছুর প্রসারিত করে না এবং এর একক পদ্ধতি রয়েছে slither()

এখন, আমরা eat()তাদের সকলের সাথে একটি পদ্ধতি যুক্ত করতে চাই ।

যদি eat()পদ্ধতির প্রয়োগটি হুবহু একই রকম হয় cat, dogএবং alligator, আমাদের একটি বেস ক্লাস তৈরি করা উচিত (যাক বলে নেওয়া যাক animal), যা এই পদ্ধতিটি কার্যকর করে।

যাইহোক, যদি এটির প্রয়োগটি alligatorসামান্যতম উপায়ে পৃথক হয়, আমাদের একটি IEatইন্টারফেস তৈরি করা উচিত mammalএবং alligatorএটি তৈরি এবং প্রয়োগ করা উচিত।

তিনি জোর দিয়েছিলেন যে এই পদ্ধতিটি সমস্ত ক্ষেত্রে আচ্ছাদন করে তবে এটি আমার কাছে অত্যধিক সরলকরণের মতো বলে মনে হয়।

থাম্ব-র এই নিয়মটি অনুসরণ করা কি উপযুক্ত?


27
alligatorএর বাস্তবায়ন eatপৃথক, অবশ্যই এটি গ্রহণ করে catএবং dogপরামিতি হিসাবে।
এসবিচেনকো

1
আপনি বাস্তবায়নগুলি ভাগ করতে সত্যিই কোনও বিমূর্ত বেস ক্লাসটি চান তবে সঠিক এক্সটেনসিবিলিটির জন্য ইন্টারফেস ব্যবহার করা উচিত, আপনি প্রায়শই এর পরিবর্তে বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন । এটি হল, যদি আপনার ভাষা এটি সমর্থন করে।
আমন

2
আপনি যখন নিজেকে কোনও কোণে আঁকেন, দরজার নিকটে থাকা অবস্থায় থাকা ভাল।
জেফো

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

2
আমার একজন সিএস প্রোফাইফ শিখিয়েছিলেন যে সুপারক্লাসগুলি হওয়া উচিত is aএবং ইন্টারফেসগুলি হ'ল acts likeবা is। সুতরাং একটি কুকুর is aস্তন্যপায়ী এবং acts likeএকটি খাওয়া। এটি আমাদের বলবে যে স্তন্যপায়ী প্রাণীর একটি শ্রেণি হওয়া উচিত এবং ভক্ষণকারী একটি ইন্টারফেস হওয়া উচিত। এটি সর্বদা একটি সহায়ক সহায়ক ছিল। সিডনোট: isহতে পারে এর একটি উদাহরণ The cake is eatableবা The book is writable
মিররফেটে

উত্তর:


13

আমি মনে করি না যে এটি একটি থাম্বের একটি ভাল নিয়ম। আপনি যদি কোড পুনরায় ব্যবহার সম্পর্কে উদ্বিগ্ন হন তবে আপনি PetEatingBehaviorবিড়াল এবং কুকুরের খাওয়ার ক্রিয়াকলাপ সংজ্ঞায়িত করতে কোন ভূমিকাটি কার্যকর করতে পারেন । তারপরে আপনি IEatএবং কোড একসাথে পুনরায় ব্যবহার করতে পারেন ।

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

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

সমৃদ্ধ হিকিকে উদ্ধৃত করা: সহজ! = সহজ


আপনি PetEatingBehaviorবাস্তবায়নের একটি প্রাথমিক উদাহরণ প্রদান করতে পারেন ?
এসবিচেনকো

1
@exizt প্রথমত, নামগুলি বেছে নেওয়ার ক্ষেত্রে আমি খারাপ। তাই PetEatingBehaviorসম্ভবত ভুল এক। আমি আপনাকে বাস্তবায়ন দিতে পারছি না কারণ এটি কেবল খেলনার উদাহরণ। তবে আমি রিফ্যাক্টরিং পদক্ষেপগুলি বর্ণনা করতে পারি: এটির একটি নির্মাণকারী রয়েছে যা বিড়াল / কুকুর দ্বারা eatপদ্ধতিটি নির্ধারণের জন্য ব্যবহৃত সমস্ত তথ্য গ্রহণ করে (দাঁতগুলির উদাহরণ, পেটের উদাহরণ ইত্যাদি)। এটিতে কেবল তাদের eatপদ্ধতিতে ব্যবহৃত বিড়াল এবং কুকুরের জন্য প্রচলিত কোড রয়েছে । আপনাকে কেবল একটি PetEatingBehaviorসদস্য তৈরি করতে হবে এবং এটি ক্রেগ.ইয়েট / কেট.াইটে কল করে।
সাইমন বার্গোট

উত্তরাধিকার থেকে দূরে ওপি চালিত করা অনেকের একমাত্র এই উত্তর আমি বিশ্বাস করতে পারি না :( উত্তরাধিকার কোড পুনরায় ব্যবহারের জন্য নয়!
ড্যানি টুপেনি

1
@ ড্যানি টুপেনি কেন নয়?
এসবিচেনকো

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

11

থাম্ব-র এই নিয়মটি অনুসরণ করা কি উপযুক্ত?

এটি থাম্বের একটি শালীন নিয়ম, তবে আমি যেখানে বেশিরভাগ জায়গায় এটি লঙ্ঘন করেছি তা জানি।

সত্যি কথা বলতে, আমি আমার সমবয়সীদের তুলনায় বেস ক্লাসগুলি অনেক বেশি ব্যবহার করি (বিমূর্ত)। আমি ডিফেন্সিভ প্রোগ্রামিং হিসাবে এটি করি।

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

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


1
এই উত্তরটি 3 বছর পরে পুনরায় পড়া, আমি এটি একটি দুর্দান্ত বিষয় বলে মনে করি: একটি ইন্টারফেসের চেয়ে বেস ক্লাসটি বেছে নেওয়ার মাধ্যমে আপনি বলছেন "এটিই ক্লাসের মূল কার্যকারিতা (এবং কোনও উত্তরাধিকারী), এবং এটি হ'ল অন্যান্য কার্যকারিতার সাথে
উইলি

9

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

কার্যকারিতা কী বলে মনে করেন তা দেখে আপনার কী করা উচিত তা আবিষ্কার করার পরিবর্তে, আপনি যে স্তরক্রমটি তৈরির চেষ্টা করছেন তার দিকে নজর দিন।

আমার একজন অধ্যাপক কীভাবে পার্থক্যটি শিখিয়েছিলেন:

সুপারক্লাসগুলি হওয়া উচিত is aএবং ইন্টারফেসগুলি হয় acts likeবা is। সুতরাং একটি কুকুর is aস্তন্যপায়ী এবং acts likeএকটি খাওয়া। এটি আমাদের বলবে যে স্তন্যপায়ী প্রাণীর একটি শ্রেণি হওয়া উচিত এবং ভক্ষণকারী একটি ইন্টারফেস হওয়া উচিত। isহবে The cake is eatableবা The book is writable(উভয় eatableএবং writableইন্টারফেস) তৈরির একটি উদাহরণ ।

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

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

শুধু আমার দুই সেন্ট।


6

এক্সিজ্টের অনুরোধে, আমি আমার মন্তব্যটি আরও দীর্ঘ উত্তরে প্রসারিত করছি।

লোকেরা যে বৃহত্তম ভুলটি বিশ্বাস করে তা হল ইন্টারফেসগুলি কেবল খালি বিমূর্ত শ্রেণি। একটি ইন্টারফেস একটি প্রোগ্রামারকে বলার একটি উপায়, "আপনি যতটা আমাকে দেন তা আমি ততক্ষণ বিবেচনা করি না যতক্ষণ না এটি এই সম্মেলনটি অনুসরণ করে।"

.NET গ্রন্থাগারটি একটি দুর্দান্ত উদাহরণ হিসাবে কাজ করে। উদাহরণস্বরূপ, আপনি যখন কোনও ফাংশন লেখেন যা কোনও গ্রহণ করে IEnumerable<T>, আপনি যা বলছেন তা হ'ল " আপনি কীভাবে আপনার ডেটা সংরক্ষণ করছেন তা আমি বিবেচনা করি না I আমি কেবল জানতে চাই যে আমি একটি foreachলুপ ব্যবহার করতে পারি ।

এটি কিছু খুব নমনীয় কোড বাড়ে। হঠাৎ সংহত করার জন্য, আপনাকে যা করতে হবে তা হ'ল বিদ্যমান ইন্টারফেসের নিয়ম অনুসারে খেলতে হবে। যদি ইন্টারফেস বাস্তবায়ন করা কঠিন বা বিভ্রান্তিকর হয়, তবে সম্ভবত এটি এমন একটি ইঙ্গিত যা আপনি একটি বৃত্তাকার ছিদ্রটি একটি বৃত্তাকার গর্তে নিক্ষেপ করার চেষ্টা করছেন।

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

উত্তরাধিকার ব্যবহারের কারণে আপনি "কোড পুনরায় ব্যবহার" শব্দের শব্দ পছন্দ করেন এটি একটি খুব খারাপ ধারণা। Google দ্বারা কোড স্টাইলিং নির্দেশিকা এই বিন্দু মোটামুটি সংক্ষেপে তোলে:

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

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

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

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

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

Inherit উত্তরাধিকার বর্ণনা করার সময়, সবাই প্রাণী ব্যবহার করে। তা অকেজো। 11 বছরের বিকাশে, আমি কখনও নামে একটি শ্রেণি লিখিনি Cat, তাই আমি এটি উদাহরণ হিসাবে ব্যবহার করব না।


সুতরাং, যদি আমি আপনাকে সঠিকভাবে বুঝতে পারি, নির্ভরতা ইনজেকশন উত্তরাধিকার হিসাবে একই কোড পুনরায় ব্যবহারের ক্ষমতা সরবরাহ করে। তবে আপনি কীসের জন্য উত্তরাধিকার ব্যবহার করবেন? আপনি একটি ব্যবহার-কেস সরবরাহ করবেন? (আমি এর সাথে সত্যই প্রশংসা করেছি FileStream)
এসবিচেনকো

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

4

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

আপনি এই ক্ষেত্রে বিমূর্ত আচরণ দ্বারা ভাল এই ক্ষেত্রে:

public interface IFoodEater
{
    void Eat(IFood food);
}

public class Animal : IFoodEater
{
    private IFoodProcessor _foodProcessor;
    public Animal(IFoodProcessor foodProcessor)
    {
        _foodProcessor = foodProcessor;
    }

    public void Eat(IFood food)
    {
        _foodProcessor.Process(food);
    }
}

বা এমন কোনও দর্শনার্থীর প্যাটার্ন বাস্তবায়ন করুন যেখানে FoodProcessorসামঞ্জস্যপূর্ণ প্রাণী ( ICarnivore : IFoodEater, MeatProcessingVisitor) খাওয়ানোর চেষ্টা করা হয় । জীবন্ত প্রাণীগুলির চিন্তাভাবনাগুলি তাদের হজম ট্র্যাকটি ছিঁড়ে ফেলার এবং জেনেরিকের পরিবর্তে এটি প্রতিস্থাপনের বিষয়ে ভাবতে বাধা দিতে পারে তবে আপনি সত্যই তাদের অনুগ্রহ করছেন।

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

হ্যাঁ, বেস ক্লাসগুলির তাদের জায়গা রয়েছে, থাম্বের নিয়মটি প্রয়োগ হয় (প্রায়শই, সর্বদা নয়, কারণ এটি থাম্বের নিয়ম) তবে এমন আচরণের সন্ধান করুন যা আপনি বিচ্ছিন্ন করতে পারেন।


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

1
মাংসাশী গাছ সম্পর্কে কি? :) সিরিয়াসলি, এই ক্ষেত্রে ইন্টারফেস ব্যবহার না করার একটি বড় সমস্যা হ'ল আপনি প্রাণীর সাথে খাওয়ার ধারণাটি ঘনিষ্ঠভাবে বেঁধে রেখেছেন এবং নতুন বিমূর্ততা প্রবর্তনের জন্য এটি আরও অনেক বেশি কাজ যার জন্য প্রাণী বেস শ্রেণি যথাযথ নয়।
জুলিয়া হ্যাওয়ার্ড

1
আমি বিশ্বাস করি "খাওয়া" এখানে ভুল ধারণা: আরও বিমূর্ত হয়ে যান go কিভাবে একটি IConsumerইন্টারফেস সম্পর্কে । মাংসাশী মাংস খাওয়াতে পারে, নিরামিষভোজী গাছপালা গ্রাস করতে পারে এবং গাছপালা সূর্যের আলো এবং জল গ্রহণ করে।

2

একটি ইন্টারফেস সত্যিই একটি চুক্তি। কোনও কার্যকারিতা নেই। এটি বাস্তবায়ন করা বাস্তবায়নকারীর উপর নির্ভর করে। চুক্তিটি কার্যকর করতে হবে বলে কোনও বিকল্প নেই।

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

উদাহরণ স্বরূপ:

public abstract class Person
    {
        /// <summary>
        /// Inheritors must implement a hello
        /// </summary>
        /// <returns>Hello</returns>
        public abstract string SayHello();
        /// <summary>
        /// Inheritors can use base functionality, or override
        /// </summary>
        /// <returns></returns>
        public virtual string SayGoodBye()
        {
            return "Good Bye";
        }
        /// <summary>
        /// Base Functionality that is inherited 
        /// </summary>
        public void DoSomething()
        {
            //Do Something Here
        }
    }

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

এখন যদি "খাওয়ার" সংজ্ঞাটি প্রাণী থেকে প্রাণীর মধ্যে পৃথকভাবে পরিবর্তিত হয় তবে সম্ভবত এবং ইন্টারফেসটি আরও ভাল হবে। এটি কখনও কখনও ধূসর অঞ্চল এবং পৃথক পরিস্থিতির উপর নির্ভর করে।


1

না।

ইন্টারফেসগুলি পদ্ধতিগুলি কীভাবে প্রয়োগ করা হয় সে সম্পর্কে। যদি আপনি কীভাবে পদ্ধতিগুলি প্রয়োগ করা হবে সে সম্পর্কে ইন্টারফেসটি ব্যবহার করার সিদ্ধান্তের ভিত্তিতে বসে থাকেন তবে আপনি কিছু ভুল করছেন।

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

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


দাঁড়াও, কেন পুনরায় বাস্তবায়ন eat()মধ্যে যে পশু? আমরা mammalএটি বাস্তবায়ন করতে পারি, তাই না? যদিও প্রয়োজনীয়তাগুলি সম্পর্কে আপনার বক্তব্যটি আমি বুঝতে পারি।
এসবিচেনকো

@ এক্সিজট: দুঃখিত, আমি আপনার প্রশ্নটি ভুলভাবে পড়েছি।
ইউফোরিক

1

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

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

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


1

আমি এই প্রশ্নের উত্তর নিজেই দেখার চেষ্টা করছি, অন্য লোকেরা কী বলবে তা দেখার জন্য, তবে আমি তিনটি বিষয় বলব যা সম্পর্কে আমি ভাবতে আগ্রহী:

  1. মানুষ ইন্টারফেসে খুব বেশি বিশ্বাস রাখে, এবং ক্লাসে খুব কম বিশ্বাস রাখে। ইন্টারফেসগুলি মূলত বেস ক্লাসগুলিতে খুব জল সরবরাহ করা হয় এবং হালকা ওজনের কিছু ব্যবহার করার ফলে অতিরিক্ত বয়লারপ্লিট কোডের মতো জিনিসগুলি হতে পারে।

  2. কোনও পদ্ধতিকে ওভাররাইড করা, এর super.method()মধ্যে কল করা এবং তার শরীরের বাকি অংশগুলিকে কেবল এমন কাজ করতে দেওয়া উচিত যা বেস বর্গের সাথে হস্তক্ষেপ না করে। এটি লিসকোব সাবস্টিটিউশন নীতি লঙ্ঘন করে না ।

  3. থাম্বের নিয়ম হিসাবে, সফ্টওয়্যার ইঞ্জিনিয়ারিংয়ের এই অনমনীয় এবং কৌতূহলী হওয়া একটি খারাপ ধারণা, এমনকি যদি কিছু সাধারণভাবে একটি সর্বোত্তম অনুশীলন হয়।

সুতরাং আমি যা বলেছিলাম তা নুনের দানা দিয়ে নিয়ে যাব।


5
People put way too much faith into interfaces, and too little faith into classes.হাস্যকর. আমি মনে করি যে বিপরীতটি সত্য is
সাইমন বার্গোট

1
"এটি লিসকোভ সাবস্টিটিউশন নীতি লঙ্ঘন করে না" " তবে এটি এলএসপির লঙ্ঘন হয়ে উঠতে চূড়ান্ত। দুঃখের চেয়ে নিরাপদ থাকা ভাল।
ইউফোরিক

1

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

একটি ইন্টারফেস একটি চুক্তি।

IAnimalইন্টারফেস হ'ল অ্যালিগেটর, বিড়াল, কুকুর এবং একটি প্রাণীর ধারণার মধ্যে একটি সমস্ত বা কিছুই না চুক্তি। এটি মূলত যা বলে তা হ'ল "যদি আপনি প্রাণী হতে চান তবে হয় আপনার অবশ্যই এই সমস্ত গুণাবলী এবং বৈশিষ্ট্য থাকতে হবে অথবা আপনি আর প্রাণী নন"।

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


0

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

আমি @ পানজারক্রিসিসের সাথেও একমত যে থাম্বের নিয়মটি কেবল একটি সাধারণ নির্দেশিকা হওয়া উচিত। পাথরে লেখা উচিত এমন কিছু নয়। নিঃসন্দেহে এমন সময় আসবে যেখানে এটি ঠিক কাজ করে না।


-1

ইন্টারফেস প্রকারভেদ। তারা বাস্তবায়ন প্রদান করে না। এগুলি হ্যান্ডেল করার জন্য তারা সাধারণভাবে চুক্তিটি সংজ্ঞায়িত করে। এই চুক্তিটি ইন্টারফেস প্রয়োগকারী যে কোনও শ্রেণীর দ্বারা পূরণ করতে হবে।

ইন্টারফেস এবং বিমূর্ত / বেস ক্লাসের ব্যবহার ডিজাইনের প্রয়োজনীয়তা দ্বারা নির্ধারণ করা উচিত।

একটি একক শ্রেণীর ইন্টারফেসের প্রয়োজন হয় না।

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

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

উত্তরাধিকারের উপরে পছন্দসই রচনা - এই সমস্ত কিছু চলে যায়।

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