পলিমারফিজমের প্রসঙ্গে উপ-প্রকারের জন্য যুক্ত পদ্ধতিগুলি কীভাবে পরিচালনা করবেন?


14

যখন আপনি পলিমারফিজম ধারণাটি ব্যবহার করেন আপনি একটি শ্রেণিবৃত্তি তৈরি করেন এবং পিতামাতার রেফারেন্স ব্যবহার করে আপনি কোন নির্দিষ্ট ধরণের অবজেক্টটি না জেনে ইন্টারফেস ফাংশনটি কল করেন। এটা অসাধারণ. উদাহরণ:

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

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


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

24
আপনি যদি পদ্ধতিটির Eaterসাথে ইন্টারফেসটি সংজ্ঞায়িত করেন eat(), তবে ক্লায়েন্ট হিসাবে, আপনার কোনও যত্ন নেই যে Humanএটি প্রয়োগকারীকে প্রথমে কল করতে হবে washHands()এবং getDressed()এটি এই শ্রেণীর প্রয়োগের বিবরণ। যদি, একজন ক্লায়েন্ট হিসাবে, আপনি এই সত্যটির প্রতি যত্নশীল হন, তবে আপনি সম্ভবত কাজের জন্য সঠিক সরঞ্জামটি ব্যবহার করছেন না।
ভিনসেন্ট সাভার্ড 14

3
আপনাকে এও বিবেচনা করতে হবে যে সকালে যখন একজন মানুষের getDressedতাদের আগে প্রয়োজন হতে পারে eat, এটি মধ্যাহ্নভোজনের ক্ষেত্রে নয়। আপনার পরিস্থিতিতে উপর নির্ভর করে washHands();if !dressed then getDressed();[code to actually eat]মানুষের জন্য এটি বাস্তবায়নের সেরা উপায় হতে পারে। আরেকটি সম্ভাবনা হ'ল যদি অন্য জিনিসগুলির প্রয়োজন হয় washHandsএবং / অথবা getDressedবলা হয়? ধরুন তো leaveForWork? আপনার প্রোগ্রামের প্রবাহকে এমনভাবে তৈরি করার জন্য আপনার কাঠামোগত প্রয়োজন হতে পারে যা এটির আগেই বলা হয়ে থাকে।
ডানকান এক্স সিম্পসন

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

3
পশুর মতো ওও শ্রেণিবিন্যাসের স্কুল কক্ষের উদাহরণগুলি থেকে সাবধান থাকুন। রিয়েল প্রোগ্রামগুলিতে প্রায় কখনও এই জাতীয় পরিষ্কার কর থাকে না। যেমন, ericlippert.com/2015/04/27/wizards-and-warriors-part-one । অথবা আপনি যদি পুরো দোষটি দেখতে চান এবং পুরো দৃষ্টান্তটি প্রশ্ন করতে চান: অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংটি খারাপ
jpmc26

উত্তর:


18

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

উদাহরণস্বরূপ, আপনি সকালে বলেছিলেন বিভিন্ন প্রাণী বিভিন্ন জিনিস করে। কিভাবে আপনার সম্পর্কে একটি পদ্ধতি প্রবর্তন getUp()বা prepareForDay()বা ওই জাতীয় কিছু। তারপরে আপনি পলিমারফিজমটি চালিয়ে যেতে পারেন এবং প্রতিটি প্রাণীকে তার সকালের রুটিন সম্পাদন করতে দিন।

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

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


33

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

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

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

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

Vehicle
Road
Signal

আমরা পথচারী এবং ট্রেনগুলির সমস্ত ধরণের সাথে আরও গভীরতর যেতে পারি তবে আমরা এটি সহজ রাখব।

আসুন বিবেচনা করা যাক Vehicle। যানবাহনের কী কী সক্ষমতা প্রয়োজন? এটি একটি রাস্তায় ভ্রমণ প্রয়োজন। এটি সিগন্যাল থামাতে সক্ষম হওয়া প্রয়োজন। এটি চৌরাস্তা নেভিগেট করতে সক্ষম হওয়া প্রয়োজন।

interface Vehicle {
  move(Road road);
  navigate(Road... intersection);
}

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

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

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


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

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

@ jpmc26 সম্ভবত কিছুটা জোরালো শব্দ করা হয়েছে। আমি নিশ্চিত নই যে আমি এটিকে বাস্তবায়িত করা বিরল that আমি নিশ্চিত না যে ইন্টারফেসগুলি কীভাবে কার্যকর হতে পারে যদি আপনি মার্কার ইন্টারফেসগুলি বাদ দিয়ে এইভাবে ব্যবহার না করেন যা আমার মনে হয় যে এটি একটি ভয়ঙ্কর ধারণা।
জিমি জেমস

9

টি এল; ডিআর:

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

আসুন প্রথমে আপনার eat()উদাহরণ সহ থাকি ।

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

সফ্টওয়্যার ফিরে:

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

কি হবে makeEggs()?

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


আমি এই উত্তরের সাথে একমত কোড গন্ধ সম্পর্কে নরেক ঠিক। এটি ইন্টারফেস ডিজাইন যা দুর্গন্ধযুক্ত, তাই এটি এবং আপনার ভালটি ঠিক করুন।
জোনাথন ভ্যান ডি ভীন

এই উত্তরটি যা বর্ণনা করে তা সাধারণত লিসকভ সাবস্টিটিউশন নীতি হিসাবে উল্লেখ করা হয় ।
ফিলিপ

2

উত্তরটা বেশ সাধারন.

আপনার প্রত্যাশার চেয়ে আরও বেশি কিছু করতে পারে এমন কীভাবে পরিচালনা করবেন?

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

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

উদাহরণস্বরূপ, সিউডোকোডে:

interface IEater { void Eat(); }
interface IMorningRoutinePerformer { void DoMorningRoutine(); }
interface IAnimal : IEater, IMorningPerformer;
interface IHuman : IEater, IMorningPerformer; 
{
  void WashHands();
  void GetDressed();
}

void MorningTime()
{
   IList<IMorningRoutinePerformer> items = Service.GetMorningPerformers();
   foreach(item in items) { item.DoMorningRoutine(); }
}

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

পলিমারফিজম মারা যায়।

নাকি তা করে?

আপনাকে অবজেক্টের ধরণটি খুঁজে বের করতে হবে

কেন ধরে নিচ্ছেন? আমি মনে করি এটি একটি ভুল ধারণা হতে পারে।

এই মামলাগুলি পরিচালনা করার জন্য কি কোনও সাধারণ পদ্ধতি রয়েছে?

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

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

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

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


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