ঘোড়ার একটি ঝাঁক দেওয়া, আমি কীভাবে সমস্ত ইউনিকর্নের গড় শিংয়ের দৈর্ঘ্য খুঁজে পাই?


30

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

আমি কমপক্ষে একটি .NET ফ্রেমওয়ার্ক পদ্ধতিটি ভাবতে পারি যা Enumerable.OfType<T>পদ্ধতির মতো এই সমস্যা সমাধানের উদ্দেশ্যে is তবে শেষ পর্যন্ত রানটাইমের সময় আপনি কোনও অবজেক্টের ধরণের জিজ্ঞাসাবাদ শেষ করে আমার সাথে ঠিক বসে না।

প্রতিটি ঘোড়া জিজ্ঞাসা করা ছাড়াও "আপনি কি এককেশী?" নিম্নলিখিত পদ্ধতিগুলিও মাথায় আসে:

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

আমার অনুভূতি আছে যে এটি একটি "উত্তর না দিয়ে" সেরা উত্তর দেওয়া হবে। তবে আপনি কীভাবে এই সমস্যার কাছে যান এবং যদি এটি নির্ভর করে তবে আপনার সিদ্ধান্তের প্রেক্ষাপট কী?

আমি এই সমস্যাটি এখনও কার্যকরী কোডে বিদ্যমান কিনা সে বিষয়ে কোনও অন্তর্দৃষ্টি সম্পর্কে আগ্রহী হব (বা সম্ভবত এটি কেবলমাত্র কার্যকরী ভাষায় বিদ্যমান যা মিউটিভিটি সমর্থন করে?)

এটি নিম্নলিখিত প্রশ্নের সম্ভাব্য সদৃশ হিসাবে পতাকাঙ্কিত করা হয়েছিল: ডাউন কাস্টিং এড়াবেন কীভাবে?

এই প্রশ্নের উত্তর ধরে নেওয়া হয় যে একটির দখলে HornMeasurerযার মাধ্যমে সমস্ত শিংয়ের পরিমাপ করা উচিত। তবে এটি একটি কোডবেসে বেশ চাপিয়ে দেওয়া হয়েছে যা সমতাবাদী নীতির ভিত্তিতে গঠিত হয়েছিল যে প্রত্যেককে একটি ঘোড়ার শিং পরিমাপ করতে স্বাধীন হতে হবে।

অনুপস্থিত একটি HornMeasurer, গৃহীত উত্তরের পদ্ধতির উপরের তালিকাভুক্ত ব্যতিক্রম-ভিত্তিক পদ্ধতির আয়না রয়েছে।

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


22
ঘোড়াগুলির শিং নেই, সুতরাং গড় অপরিবর্তিত (0/0)।
স্কট হুইটলক

3
10 থেকে অনন্ত পর্যন্ত কোথাও @ মোয়ারবাইলারপ্লেট করুন।
আয়া

4
@ স্টেফেনপি: এটি এই ক্ষেত্রে গাণিতিকভাবে কাজ করবে না; এই সমস্ত 0s গড় স্কিউ হবে।
ম্যাসন হুইলার

3
আপনার প্রশ্নের উত্তর যদি উত্তরহীন দিয়ে দেওয়া হয় তবে তা কোনও প্রশ্নোত্তর সাইটের অন্তর্ভুক্ত নয়; রেডডিট, কোওড়া, বা অন্যান্য আলোচনা ভিত্তিক সাইটগুলি নন-উত্তর টাইপের স্টাফগুলির জন্য নির্মিত হয়েছে ... যেটি বলেছিল, আমি মনে করি আপনি @ মেসনওহিলার প্রদত্ত কোডটি সন্ধান করলে এটি স্পষ্টভাবে জবাবদিহি হতে পারে, যদি না আমার মনে হয় আমার কোনও ধারণা নেই আপনি যা চাইতে চাইছেন ..
জিমি হোফা

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

উত্তর:


11

ধরে নিই যে আপনি Unicornএকটি বিশেষ ধরণের হিসাবে বিবেচনা করতে চান Horse, মূলত দুটি উপায় রয়েছে যা আপনি এটির মডেল করতে পারেন। আরও প্রচলিত উপায় হ'ল সাবক্লাস সম্পর্ক। আপনি যে ধরণের বিষয় বিবেচনা করেন তা সর্বদা তালিকাগুলিকে আলাদা রাখতে কেবল আপনার কোডটিকে পুনরায় ব্যবহার করে ধরণ এবং ডাউনকাস্টিং এড়াতে পারবেন এবং কেবল সেই Unicornবৈশিষ্ট্যগুলিতেই মিলিত করুন যেখানে আপনি কখনই বৈশিষ্ট্যের বিষয়ে চিন্তা করেন না । অন্য কথায়, আপনি এটি ব্যবস্থা করেন যাতে আপনি কখনই এমন পরিস্থিতিতে না পড়েন যেখানে আপনাকে প্রথমে ঘোড়ার পাল থেকে ইউনিকর্ন তোলা দরকার। এটি প্রথমে কঠিন বলে মনে হচ্ছে তবে 99.99% ক্ষেত্রে এটি সম্ভব এবং সাধারণত আপনার কোডটিকে অনেক পরিষ্কার করে তোলে।

আপনি কোনও ইউনিকর্ন মডেল করার অন্য উপায়টি হ'ল সমস্ত ঘোড়াগুলিকে একটি anচ্ছিক শিংয়ের দৈর্ঘ্য দেওয়া। তারপরে আপনি এটি শিংয়ের দৈর্ঘ্য আছে কিনা তা পরীক্ষা করে কোনও ইউনিকর্ন কিনা তা পরীক্ষা করে দেখতে পারেন এবং (ইউকেউলে) দ্বারা সমস্ত ইউনিকর্নের গড় শিংয়ের দৈর্ঘ্যটি খুঁজে বের করতে পারেন:

case class Horse(val hornLength: Option[Double])

val horse = Horse(None)
val unicorn = Horse(Some(12.0))
val anotherUnicorn = Horse(Some(6.0))

val herd = List(horse, unicorn, anotherUnicorn)
val hornLengths = herd flatMap {_.hornLength}
val averageLength = hornLengths.sum / hornLengths.size

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


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

@ ম্যাসনওহিলার কেবল দ্বিতীয় পদ্ধতিতে উপস্থাপন করেছেন।
moarboilerplate

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

1
আপত্তি যদি আপনি একটি স্বতন্ত্র সম্পত্তি এককূপ বৈশিষ্ট্য encapsulate এবং অত্যন্ত সচেতন হয় - কেন নিজের জন্য জীবন কঠিন করা। সরাসরি টাইপফুল ব্যবহার করুন এবং ভবিষ্যতের সমস্যার এক টন সংরক্ষণ করুন।
gbjbaanb

@gbjbaanb আমি সেই পদ্ধতির জন্য শুধুমাত্র সেই পদ্ধতির জন্য বিবেচনা করব যেখানে কোনও রক্তাল্পের শিংয়ের দৈর্ঘ্য সহ Horseএকটি IsUnicornসম্পত্তি এবং এক ধরণের সম্পত্তি ছিল UnicornStuff(যখন আপনার প্রশ্নে উল্লিখিত রাইডার / গ্লিটারের জন্য স্কেলিং করা হবে)।
moarboilerplate

38

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

ব্যক্তিগতভাবে, আমি কেবল সাথে যাব horses.OfType<Unicorn>().Average(u => u.HornLength)। এটি কোডটির উদ্দেশ্যটি খুব স্পষ্টভাবে প্রকাশ করে, যে কারওর পরে এটি বজায় রাখা শেষ হওয়ার পরে সবচেয়ে গুরুত্বপূর্ণ বিষয় হয়।


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

1
কোনও উদ্বেগ নেই, তালিকায় কেবল Unicornযেভাবেই থাকে ( সমস্যাটি যে রেকর্ডটি আপনি বাদ দিতে পারেন return) একবার সমস্যাটি বেশ সমাধান হয়ে যায় ।
moarboilerplate

4
আমি যদি এই সমস্যাটি দ্রুত সমাধান করতে চাই তবে আমি উত্তরটি যাব। তবে কোডটি আরও দুর্ভাগ্যজনক হওয়ার জন্য যদি আমি রিফ্যাক্টর করতে চাইতাম তবে উত্তরটি নয়।
অ্যান্ডি

6
আপনার অবশ্যই কিছু অপরিচ্ছন্ন স্তরের অপ্টিমাইজেশন না লাগলে এটি অবশ্যই উত্তর। এর স্পষ্টতা এবং পঠনযোগ্যতা অন্য সব কিছুকে প্রশমিত করে তোলে।
ডেভিড মনিকাকে পুনরায়

1
@ ডেভিডগ্রিনবার্গ এই পরিষ্কার, পঠনযোগ্য পদ্ধতির লেখার অর্থ কী হল যে আপনাকে আগে একটি উত্তরাধিকার কাঠামো প্রয়োগ করতে হবে যা আগে ছিল না?
moarboilerplate

9

নেট। এর সাথে কোনও ভুল নেই:

var unicorn = animal as Unicorn;
if(unicorn != null)
{
    sum += unicorn.HornLength;
    count++;
}

লিনক সমতুল্য ব্যবহার করাও ভাল:

var averageUnicornHornLength = animals
    .OfType<Unicorn>()
    .Select(x => x.HornLength)
    .Average();

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

var averageHornedAnimalHornLength = animals
    .OfType<IHornedAnimal>()
    .Select(x => x.HornLength)
    .Average();

নোট যখন Linq ব্যবহার করে Average(এবং Minএবং Max) যদি গণনীয় খালি একটি ব্যতিক্রম নিক্ষেপ এবং টাইপ টি nullable নয় হবে। এটি হ'ল গড়টি সত্যই অপরিশোধিত (0/0)। সুতরাং সত্যিই আপনার এইরকম কিছু দরকার:

var hornedAnimals = animals
    .OfType<IHornedAnimal>()
    .ToList();
if(hornedAnimals.Count > 0)
{
    var averageHornLengthOfHornedAnimals = hornedAnimals
        .Average(x => x.HornLength);
}
else
{
    // deal with it in your own way...
}

সম্পাদন করা

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

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

অন্যদিকে, আপনি যদি কোনও ডেটা স্ট্রাকচার বা ডেটা মডেল তৈরির জন্য ক্লাস / অবজেক্ট / ইন্টারফেস আইডিয়াগুলি ব্যবহার করে (ভুল) হন, তবে আমি ব্যক্তিগতভাবে-ই-ধারণাটি সম্পূর্ণরূপে ব্যবহার করতে কোনও সমস্যা দেখতে পাচ্ছি না। আপনি যদি সংজ্ঞায়িত করেছেন যে ইউনিকর্নগুলি একটি উপ-ধরণের ঘোড়া এবং এটি আপনার ডোমেনের মধ্যে সম্পূর্ণরূপে উপলব্ধি করে, তবে একেবারে এগিয়ে যান এবং ইউনিকর্নগুলি খুঁজতে আপনার পশুর ঘোড়াগুলিকে জিজ্ঞাসা করুন। সর্বোপরি, এরকম ক্ষেত্রে আমরা সাধারণত আমাদের যে সমস্যার সমাধান করতে হবে তার সমাধানগুলি আরও ভালভাবে প্রকাশ করার জন্য একটি ডোমেন নির্দিষ্ট ভাষা তৈরি করার চেষ্টা করছি। এই অর্থে .OfType<Unicorn>()ইত্যাদিতে কোনও ভুল নেই etc.

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


7
আপনি ইতিমধ্যে জানেন যে animal এটি একটি Unicorn ; কেবল ব্যবহারের পরিবর্তে কাস্ট করুন as, বা সম্ভবত আরও ভাল ব্যবহার করুন as এবং তারপরে শূন্যতার জন্য পরীক্ষা করুন।
ফিলিপ কেন্ডল

3

তবে শেষ পর্যন্ত রানটাইমের সময় আপনি কোনও অবজেক্টের ধরণের জিজ্ঞাসাবাদ শেষ করে আমার সাথে ঠিক বসে না।

এই বিবৃতিতে সমস্যাটি হ'ল, আপনি যে পদ্ধতিটি ব্যবহার করেন না কেন, আপনি সর্বদা অবজেক্টটিকে কী ধরণের তা বলার জন্য জিজ্ঞাসাবাদ করবেন। এটি আরটিটিআই হতে পারে বা এটি কোনও ইউনিয়ন বা আপনি যেখানে জিজ্ঞাসা করেছেন একটি সাধারণ তথ্য কাঠামো হতে পারে if horn > 0। সঠিক সুনির্দিষ্ট কিছুটা পরিবর্তন হলেও অভিপ্রায়টি হ'ল - আপনি কোনও বিষয়টিকে নিজের সম্পর্কে আরও জিজ্ঞাসাবাদ করবেন কিনা তা জানতে কোনওভাবে নিজেকে জিজ্ঞাসা করুন।

এটি দেওয়া, এটি করার জন্য আপনার ভাষার সমর্থনটি ব্যবহার করা বোধগম্য। .NET এ আপনি typeofউদাহরণস্বরূপ ব্যবহার করবেন।

এটি করার কারণটি কেবল আপনার ভাষা ভালভাবে ব্যবহার করার বাইরে চলে যায়। আপনার যদি এমন একটি জিনিস থাকে যা দেখতে অন্যরকম লাগে তবে কিছুটা ছোট পরিবর্তনের জন্য, আপনি সময়ের সাথে আরও পার্থক্য খুঁজে পাওয়ার সম্ভাবনা রয়েছে। ইউনিকর্ন / ঘোড়ার উদাহরণে আপনি বলতে পারেন যে কেবল শিংয়ের দৈর্ঘ্য রয়েছে ... তবে আগামীকাল আপনি এটি পরীক্ষা করে দেখবেন যে কোনও সম্ভাব্য রাইডার কুমারী কিনা, বা পোপ চকচকে হয়। (একটি ক্লাসিক রিয়েল-ওয়ার্ল্ড উদাহরণ হ'ল জিইউআই উইজেটগুলি যা একটি সাধারণ বেস থেকে পাওয়া যায় এবং আপনাকে চেকবক্স এবং তালিকাবক্সগুলি আলাদাভাবে সন্ধান করতে হয় differences কেবলমাত্র একটি একক সুপার অবজেক্ট তৈরি করতে পার্থক্যের সংখ্যাটি খুব দুর্দান্ত হবে যা ডেটাগুলির সমস্ত সম্ভাব্য ক্রম ধারণাকে ধারণ করে held )।

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

অবশ্যই একটি ব্যতিক্রম ভিত্তিক পদ্ধতি ভুল is সাধারণ প্রোগ্রামের প্রবাহ হিসাবে ব্যতিক্রমগুলি ব্যবহার করা কোডের গন্ধ (যদি আপনার কাছে ইউনিকর্নের ঝাঁক এবং একটি গাধা থাকে যা মাথায় ছিনতাই করে থাকে, তবে আমি ব্যতিক্রম ভিত্তিক পদ্ধতিটি ঠিকই বলব, তবে যদি আপনার ইউনিকর্নের ঝাঁক থাকে এবং ঘোড়াগুলি পরে ইউনিকর্ন-নেসের জন্য প্রত্যেকের পরীক্ষা করা অপ্রত্যাশিত নয় Ex ব্যতিক্রমগুলি ব্যতিক্রমী পরিস্থিতিতে, জটিল ifবক্তব্য নয়)। যাই হোক না কেন, এই সমস্যার জন্য ব্যতিক্রমগুলি ব্যবহার করা কেবল রানটাইমের সময় অবজেক্টের ধরণের বিষয়ে জিজ্ঞাসাবাদ করা হয়, কেবলমাত্র আপনি এখানে অ-ইউনিকর্ন অবজেক্টগুলি পরীক্ষা করতে ভাষা বৈশিষ্ট্যটির অপব্যবহার করছেন। আপনি পাশাপাশি একটি কোড করতে পারেনif horn > 0 এবং কমপক্ষে আপনার সংকলনটি দ্রুত, স্পষ্টভাবে, কোডের কম লাইন ব্যবহার করে এবং অন্যান্য ব্যতিক্রমগুলি ছোঁড়ার সময় উত্থাপিত কোনও সমস্যা এড়ানো থেকে বিরত রেখে প্রক্রিয়া করুন (যেমন একটি খালি সংগ্রহ, বা সেই গাধাটির সিশেল পরিমাপ করার চেষ্টা করা)


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

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

3

যেহেতু প্রশ্নটির একটি functional-programmingট্যাগ রয়েছে, আমরা ঘোড়ার দুটি স্বাদ এবং প্যাটার্নের সাথে মিলে যাবার জন্য দুটি মিলের প্রতিফলনের জন্য একটি সমষ্টি টাইপ ব্যবহার করতে পারি। উদাহরণস্বরূপ, এফ # তে:

type Equine =
| Horse
| Unicorn of hornLength: float

module equines =

  let averageHornLength (equines : Equine list) =
    equines 
    |> List.choose (fun x -> 
      match x with
      | Unicorn u -> Some(u)
      | _ -> None)
    |> List.average

let herd = [ Horse ; Horse ; Unicorn(35.0) ; Horse ; Unicorn(50.0) ]

printfn "Average horn length in herd : %f" (equines.averageHornLength herd) // prints 42.5

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

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


2

শেষে একই উত্তরের সংক্ষিপ্ত ফর্মের জন্য বই বা ওয়েব নিবন্ধ পড়া দরকার।

দর্শনার্থী প্যাটার্ন

সমস্যাটিতে ঘোড়া এবং ইউনিকর্নের মিশ্রণ রয়েছে। (লিসকোভের বিকল্প নীতি লঙ্ঘন করা লিগ্যাসি কোডবেসে একটি সাধারণ সমস্যা))

ঘোড়া এবং সমস্ত সাবক্লাসে একটি পদ্ধতি যুক্ত করুন

Horse.visit(EquineVisitor v)

অশ্বতুল্য দর্শনার্থী ইন্টারফেসটি জাভা / সি # তে এরকম কিছু দেখাচ্ছে #

interface EquineVisitor {
  void visitHorse(Horse z);
  void visitUnicorn(Unicorn z);
}

Unicorn.visit(EquineVisitor v){
   v.visitUnicorn(this);
}

Horse.visit(EquineVisitor v){
   v.visitHorse(this);
}

শিং পরিমাপ করতে আমরা এখন লিখি ....

class HornMeasurer implements EquineVistor {
    void visitHorse(Horse h){} // ignore horses
    void visitUnicorn(Unicorn u){
         double len = u.getHornLength();
         totalLength+=len;
         unicornCount++;
    }

    double getAverageLength(){
          return totalLength/unicornCount;
    }

    double totalLength=0;
    int unicornCount=0;
}

রিফ্যাক্টরিং এবং বৃদ্ধি আরও শক্তিশালী করার জন্য দর্শনার্থীর প্যাটার্নটি সমালোচিত হয়।

সংক্ষিপ্ত উত্তর: ডাবল প্রেরণ পেতে ডিজাইন প্যাটার্ন ভিজিটর ব্যবহার করুন।

এছাড়াও https://en.wikedia.org/wiki/Visitor_ Pattern দেখুন

দর্শনার্থীদের আলোচনার জন্য http://c2.com/cgi/wiki?VisitorPattern দেখুন ।

গামা এট আলোর নকশার প্যাটার্নগুলিও দেখুন।


আমি নিজেই দর্শকের প্যাটার্নটি দিয়ে উত্তর দিতে যাচ্ছিলাম। ইতিমধ্যে কেউ এটির উল্লেখ করেছে কিনা তা জানার জন্য একটি আশ্চর্যজনক উপায়টি স্ক্রোল করতে হয়েছিল!
বেন থারলি

0

ধরে নিই যে আপনার আর্কিটেকচারে ইউনিকর্নগুলি ঘোড়ার উপ-প্রজাতি এবং আপনি এমন জায়গাগুলির মুখোমুখি হন যেখানে আপনি Horseকয়েকটি সংগ্রহ করতে পারেন যেখানে আমি সেগুলির সংগ্রহ করেছি Unicorn, আমি ব্যক্তিগতভাবে প্রথম পদ্ধতিটি নিয়ে যাব ( .OfType<Unicorn>()...) কারণ এটি আপনার অভিপ্রায় প্রকাশের সবচেয়ে সহজ উপায় । যে কেউ পরে আসবেন (নিজেকে 3 মাসের মধ্যে অন্তর্ভুক্ত করুন) এর জন্য, আপনি এই কোডটি কী অর্জন করতে চাইছেন তা অবিলম্বে স্পষ্ট: ঘোড়াগুলির মধ্যে থেকে ইউনিকর্নগুলি বেছে নিন orn

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

foreach (var horse in horses)
{
    try
    {
        var length = horse.MeasureHorn();
        //...
    }
    catch (NoHornException e)
    {
        continue;
    }
}

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

আপনাকে ঘোড়াগুলিতে শিং পরীক্ষা করার জন্য যাদু মানের মূল্য যেতে বলে দেয় say সুতরাং এখন আপনার ক্লাসগুলি এইরকম কিছু দেখাচ্ছে:

class Horse
{
    public double MeasureHorn() { return -1; }
    //...
}

class Unicorn : Horse
{
    public override double MeasureHorn { return _hornLength; }
    //...
}

এখন আপনার Horseক্লাসটি ক্লাস সম্পর্কে জানতে হবে এবং যে Unicornবিষয়গুলির পক্ষে যত্ন নেয় না সেগুলি মোকাবেলার জন্য অতিরিক্ত পদ্ধতি রয়েছে। এখন কল্পনা করুন যে আপনি Pegasusএর ও Zebraউত্তরাধিকার সূত্রে প্রাপ্ত হন Horse। এখন Horseএকটি প্রয়োজন Flyসেইসাথে পদ্ধতি MeasureWings, CountStripesইত্যাদি এবং তারপর Unicornশ্রেণী এই পদ্ধতি খুব পায়। এখন আপনার ক্লাসগুলি একে অপরের সম্পর্কে জানতে হবে এবং আপনি ক্লাসগুলি এমন একাধিক পদ্ধতিতে দূষিত করেছেন যা কেবল টাইপ সিস্টেমটি জিজ্ঞাসা করা এড়ানোর জন্য সেখানে হওয়া উচিত নয় "এটি কি কোনও এককেশী?"

সুতরাং কিছু Horseবলতে কি কিছু যুক্ত করার জন্য যদি কিছু হয় Unicornএবং সমস্ত শিং পরিমাপ পরিচালনা করে? ভাল, এখন আপনাকে এই জিনিসের অস্তিত্ব পরীক্ষা করে দেখতে হবে যে কোনও কিছু ইউনিকর্ন কিনা (যা কেবল একটি চেকের জন্য অন্যের জন্য প্রতিস্থাপন করছে)। এটি জলকে কিছুটা কাদাও দেয় যে এখন আপনার হতে পারেList<Horse> unicornsএটি সত্যই সমস্ত ইউনিকর্ন ধারণ করে, তবে টাইপ সিস্টেম এবং ডিবাগারটি আপনাকে সহজেই তা বলতে পারে না। "তবে আমি জানি এটি সমস্ত অবিশ্বাস্যরূপে" আপনি বলেছেন, "নামটি এমনকি এটি বলেও" " ঠিক আছে, যদি কিছু খারাপ নামকরণ করা হয়? অথবা বলুন, আপনি এই ধারণাটি সহ কিছু লিখেছিলেন যে এটি সত্যই সব ইউনিকর্ন হবে তবে তারপরে প্রয়োজনীয়তা বদলেছে এবং এখন এতে প্যাগসিও মিশ্রিত হতে পারে? (কারণ এর আগে কখনও ঘটে না, বিশেষত লিগ্যাসি সফ্টওয়্যার / কটাক্ষিতে in) এখন টাইপ সিস্টেমটি আপনার ইউনিকর্নগুলির সাথে খুশিতে আপনার পেগাসি লাগিয়ে দেবে। যদি আপনার পরিবর্তনশীল List<Unicorn>সংকলক হিসাবে ঘোষিত হয়ে থাকে (বা রানটাইম পরিবেশ) আপনি পেগ্যাসি বা ঘোড়াগুলিতে মিশ্রিত করার চেষ্টা করেছিলেন তবে এটি উপযুক্ত ছিল।

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

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


নীরব ব্যতিক্রমটি অবশ্যই খারাপ - আমার প্রস্তাবটি এমন একটি চেক ছিল যা হবে if(horse.IsUnicorn) horse.MeasureHorn();এবং ব্যতিক্রমগুলি ধরা পড়বে না - তারা হয় তখন ট্রিগার করা হবে যখন !horse.IsUnicornআপনি এবং একটি অ্যালকোর্ণ-পরিমাপের প্রসঙ্গে থাকবেন , বা ভিতরে MeasureHornকোনও অ-ইউনিকর্নে থাকবেন। এইভাবে ব্যতিক্রম ছুঁড়ে ফেলা হলে আপনি ত্রুটিগুলি মাস্ক করবেন না, এটি সম্পূর্ণরূপে ফুঁকবে এবং এটি নির্দিষ্ট করার জন্য একটি চিহ্ন। স্পষ্টতই এটি নির্দিষ্ট কিছু পরিস্থিতিতে শুধুমাত্র উপযুক্ত, তবে এটি এমন একটি বাস্তবায়ন যা কার্যকর করার পথ নির্ধারণের জন্য ব্যতিক্রম ছোঁড়া ব্যবহার করে না।
moarboilerplate

0

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

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

তবে আমি মনে করি আইএস-এ সম্পর্কের দিকে নজর দেওয়ার আরও একটি কার্যকরী-প্রোগ্রামিং-ভিত্তিক উপায় রয়েছে যা সম্ভবত এই সমস্যাগুলির মধ্যে নেই। প্রথমত, আমরা আমাদের প্রোগ্রামে ঘোড়া এবং ইউনিকর্নদের মডেল করতে চাই, সুতরাং আমরা একটি Horseএবং একটি Unicornটাইপ করতে যাচ্ছি । এই ধরণের মানগুলি কী? ঠিক আছে, আমি এটি বলতে পারি:

  1. এই ধরণের মান হ'ল ঘোড়া এবং ইউনিকর্নের উপস্থাপনা বা বর্ণনা (যথাক্রমে);
  2. তারা হয় schematized , তারা খুব কঠোর নিয়ম অনুযায়ী নির্মাণ করছি উপস্থাপনা বা বর্ণনা-they're না মুক্ত-ফর্ম।

এটি সুস্পষ্ট মনে হতে পারে, তবে আমি মনে করি যে বৃত্ত-উপবৃত্ত সমস্যার মতো সমস্যাগুলিতে লোকেরা প্রবেশের অন্যতম উপায় হ'ল সেই বিষয়গুলি সাবধানতার সাথে বিবেচনা না করে by প্রতিটি চেনাশোনা একটি উপবৃত্তাকার, তবে এর অর্থ এই নয় যে একটি বৃত্তের প্রতিটি স্কিমাইটাইজড বিবরণ স্বয়ংক্রিয়ভাবে একটি পৃথক স্কিমা অনুযায়ী উপবৃত্তির একটি স্কিমাইটিস বিবরণ। অন্য কথায়, কেবল একটি বৃত্তটি উপবৃত্তের অর্থ এই নয় যে Circleএটি একটি Ellipse, তাই কথা বলা। তবে এর অর্থ এই:

  1. একটি মোট ফাংশন রয়েছে যা কোনও Circle(স্কিমাইটেড সার্কেলের বর্ণনা) কে Ellipse(বর্ণনার বিভিন্ন ধরণের ) রূপান্তর করে যা একই বৃত্তকে বর্ণনা করে;
  2. একটি আংশিক ফাংশন রয়েছে যা একটি গ্রহণ করে Ellipseএবং, যদি একটি বৃত্তের বর্ণনা দেয় তবে সংশ্লিষ্টটি ফিরিয়ে দেয় Circle

সুতরাং, কার্যনির্বাহী প্রোগ্রামিংয়ের ক্ষেত্রে, আপনার Unicornধরণের মোটেও একটি উপ-টাইপ হওয়ার দরকার নেই Horse, আপনার কেবল এই জাতীয় ক্রিয়াকলাপ প্রয়োজন:

-- Convert any unicorn-description of into a horse-description that
-- describes the same unicorns.
toHorse :: Unicorn -> Horse

-- If the horse described by the given horse-description is a unicorn,
-- then return a unicorn-description of that unicorn, otherwise return
-- nothing.
toUnicorn :: Horse -> Maybe Unicorn

এবং এর toUnicornসঠিক বিপরীত হওয়া দরকার toHorse:

toUnicorn (toHorse x) = Just x

Maybeঅন্যান্য ভাষার ভাষাগুলি "অপশন" টাইপকে হ্যাস্কেলের ধরণ বলে। উদাহরণস্বরূপ, জাভা 8 Optional<Unicorn>টাইপ হয় হয় Unicornবা কিছুই নয়। নোট করুন যে আপনার দুটি বিকল্প- একটি ব্যতিক্রম ছুঁড়ে ফেলা বা "ডিফল্ট বা ম্যাজিক মান" ফিরিয়ে দেওয়া —অন্য বিকল্পগুলির সাথে খুব মিল।

সুতরাং মূলত আমি এখানে যা করেছি তা হ'ল সাব-টাইপ বা উত্তরাধিকার ব্যবহার না করে ধরণ এবং প্রকারের ক্ষেত্রে IS-A সম্পর্কটিকে পুনর্গঠন করা। আমি এ থেকে যা নেব তা হ'ল:

  1. আপনার মডেল একটি Horseপ্রকারের প্রয়োজন;
  2. Horseটাইপ চাহিদা unambiguously কিনা তা নির্ধারণ করতে কোনো মান একটি unicorn বর্ণনা যথেষ্ট তথ্য এনকোড করা;
  3. Horseপ্রকারের কিছু ক্রিয়াকলাপগুলিতে সেই তথ্যটি প্রকাশ করা দরকার যাতে প্রকারের ক্লায়েন্টরা প্রদত্ত Horseএকটি ইউনিকর্ন কিনা তা পর্যবেক্ষণ করতে পারেন ;
  4. Horseধরণের ক্লায়েন্টদের ইউনিকর্ন এবং ঘোড়ার মধ্যে বৈষম্যের জন্য রানটাইমের সময়গুলিতে এই উত্তরোত্তর অপারেশনগুলি ব্যবহার করতে হবে।

সুতরাং এটি মৌলিকভাবে " Horseএটি একটি ইউনিকর্ন কিনা " প্রত্যেককে জিজ্ঞাসা করুন । আপনি সেই মডেল সম্পর্কে সতর্ক, তবে আমি ভুলভাবে এটি মনে করি। আমি যদি আপনাকে একটি তালিকা দিয়ে থাকি Horseতবে ধরণের গ্যারান্টিযুক্ত হ'ল তালিকার আইটেমগুলি যে জিনিসগুলি বর্ণনা করে তা হ'ল ঘোড়া — সুতরাং অনিবার্যভাবে আপনি রানটাইমের সময় কিছু করার প্রয়োজন যা তাদের কোনটি ইউনিকর্ন নয় tell সুতরাং এটির কাছাকাছি কিছু নেই, আমি মনে করি — আপনার এমন অপারেশনগুলি প্রয়োগ করা দরকার যা এটি আপনার জন্য করবে।

অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ে এটি করার পরিচিত উপায়টি নিম্নলিখিত:

  • একটি Horseপ্রকার আছে;
  • আছে Unicornএকটি উপপ্রকার হিসাবে Horse;
  • ক্লায়েন্ট-প্রবেশযোগ্য অপারেশন নির্ণয় একটি প্রদত্ত কিনা হিসেবে ব্যবহার করবেন রানটাইম টাইপ প্রতিফলন Horseএকটি হল Unicorn

এটির উপরে একটি বড় দুর্বলতা রয়েছে, যখন আপনি উপরে বর্ণিত "জিনিস বনাম বিবরণ" কোণ থেকে দেখেন:

  • আপনার যদি এমন কোনও Horseউদাহরণ রয়েছে যা ইউনিকর্নের বর্ণনা দেয় তবে Unicornউদাহরণ না হয়?

শুরুতে ফিরে যাওয়া, আমি মনে করি এটি হ'ল এই IS-A সম্পর্কের মডেলিংয়ের জন্য সাব টাইপিং এবং ডাউনকাস্টগুলি ব্যবহার করা সম্পর্কে সত্যই ভয়ঙ্কর অংশ - এটি আপনাকে রানটাইম চেক করতে হবে এমন নয়। টাইপোগ্রাফিকে কিছুটা অপব্যবহার করা, এটি জিজ্ঞাসা করা Horseযে এটি কোনও Unicornউদাহরণ নয় Horseকিনা এটি জিজ্ঞাসা করার জন্য এটি ইউনিকর্ন কিনা (এটি Horseঘোড়াটির একটি বিবরণ যা একটি ইউনিকর্ণও নয়) সমার্থক নয় কিনা । আপনার প্রোগ্রামটি কোড তৈরির কোডটি এনপ্যাপুলেট করার জন্য যথেষ্ট পরিমাণে না চলে যায় না যতক্ষণ না Horsesপ্রতি ক্লায়েন্ট যখন Horseকোনও ইউনিকর্ন বর্ণনা করে এমন কোনও নির্মাণের চেষ্টা করে , Unicornক্লাসটি তাত্ক্ষণিক হয়। আমার অভিজ্ঞতায় খুব কমই প্রোগ্রামাররা এগুলি সাবধানতার সাথে করে।

তাই আমি পদ্ধতির সঙ্গে যেতে চাই যেখানে কোনো স্পষ্ট, অ-হতাশ অপারেশন যে ধর্মান্তরিত নেই Horseগুলি Unicornগুলি। এটি হয় এই Horseধরণের একটি পদ্ধতি হতে পারে :

interface Horse {
    // ...
    Optional<Unicorn> toUnicorn();
}

... বা এটি কোনও বাহ্যিক বস্তু হতে পারে (আপনার "ঘোড়ার উপর পৃথক বস্তু যা আপনাকে জানায় যে ঘোড়াটি যদি এককৃমি বা না হয়"):

class HorseToUnicornCoercion {
    Optional<Unicorn> convert(Horse horse) {
       // ...
    }
}

এর মধ্যে পছন্দটি আপনার প্রোগ্রামটি কীভাবে সংগঠিত হয়েছে - এটি উভয় ক্ষেত্রেই Horse -> Maybe Unicornউপরে থেকে আমার অপারেশনের সমতুল্য রয়েছে , আপনি কেবল এটি বিভিন্ন উপায়ে প্যাকেজিং করছেন (এটি স্বীকার করবে যে টাইপটির কী কী অপারেশন Horseদরকার তা স্বীকার করতে পারে) এর ক্লায়েন্টদের কাছে প্রকাশ করা)।


-1

অন্য উত্তরে ওপির মন্তব্য প্রশ্নটি পরিষ্কার করেছে, আমি ভেবেছি

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

সেভাবে বাক্যাংশযুক্ত, আমি মনে করি আমাদের আরও তথ্যের প্রয়োজন। উত্তর সম্ভবত বেশ কয়েকটি বিষয়ের উপর নির্ভর করে:

  • আমাদের ভাষার সুবিধা। উদাহরণস্বরূপ, আমি সম্ভবত এটি রুবি এবং জাভাস্ক্রিপ্ট এবং জাভা আলাদাভাবে যোগাযোগ করতে চাই।
  • ধারণা নিজেদের কি হয় একটি ঘোড়া এবং কি হল একটি unicorn? প্রতিটি কিসের সাথে ডেটা যুক্ত? শিং বাদে এগুলি কি ঠিক একই, না তাদের অন্য পার্থক্য রয়েছে?
  • শিং দৈর্ঘ্যের গড় গ্রহণ বাদ দিয়ে আমরা কীভাবে এগুলি ব্যবহার করব? এবং পশুর সম্পর্কে কী? আমাদের কি তাদেরও মডেল করা উচিত? আমরা তাদের অন্য কোথাও ব্যবহার করি? herd.averageHornLength()আমাদের ধারণাগত মডেলের সাথে মেলে বলে মনে হচ্ছে।
  • কীভাবে ঘোড়া এবং ইউনিকর্ন অবজেক্ট তৈরি করা হচ্ছে? কোডটি কি আমাদের রিপ্যাক্টেরিংয়ের সীমানার মধ্যে পরিবর্তন করা হচ্ছে?

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

ওপি, আমি এখনও ভুল বোঝাবুঝি করছি কিনা তা আমাকে জানান ...


1
ফেয়ার পয়েন্টস। সমস্যাটিকে আরও বিমূর্ততা থেকে রক্ষা করতে আমাদের কিছু যুক্তিসঙ্গত অনুমান করতে হবে: 1) একটি দৃ typ়-টাইপিত ভাষা 2) পশুপ ঘোড়াগুলিকে এক প্রকারের মধ্যে আবদ্ধ করে, সম্ভবত সংগ্রহের কারণে 3) হাঁসের টাইপের মতো কৌশলগুলি সম্ভবত এড়ানো উচিত । কী কী পরিবর্তন করা যায়, অগত্যা কোনও সীমাবদ্ধতা নেই, তবে প্রতিটি ধরণের পরিবর্তনের নিজস্ব অনন্য পরিণতি রয়েছে ...
moarboilerplate

যদি পশুপ ঘোড়াগুলিকে এক প্রকারে আবদ্ধ করে রাখে, তবে কেবলমাত্র আমাদের পছন্দগুলি উত্তরাধিকার নয় (সেই বিকল্পটি পছন্দ করবেন না) বা একটি মোড়কযুক্ত বস্তু (বলুন HerdMember) যা আমরা একটি ঘোড়া বা ইউনিকর্ন (ঘোড়া মুক্ত করে এবং ইউনিকর্নকে একটি উপ-টাইপের সম্পর্কের প্রয়োজন থেকে শুরু করে) দিয়ে শুরু করি )। HerdMemberতারপরে isUnicorn()এটি যথাযথ দেখায় তবে বাস্তবায়নের জন্য নিখরচায় এবং আমার প্রস্তাবিত ফিল্টারিং সমাধানটি অনুসরণ করে।
জোনাহ

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

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

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

-2

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


আমি এটার সাথে একমত. ম্যাসন হুইলার পাশাপাশি তার উত্তর একটি ভাল সমাধান আছে, কিন্তু আপনি যদি বিভিন্ন জায়গায় বিভিন্ন কারণে একক আউট ইউনিকর্ন করতে হবে, আপনার কোড অনেক আছে হবে horses.ofType<Unicorn>...নির্মান। একটি GetUnicornsফাংশন থাকা ওয়ান-লাইনার হবে, তবে এটি কলারের দৃষ্টিকোণ থেকে ঘোড়া / ইউনিকর্নের সম্পর্কের পরিবর্তনের ক্ষেত্রে আরও প্রতিরোধী হবে।
শাজ

@ রায়ান যদি আপনি কোনও ফিরিয়ে দেন IEnumerable<Horse>তবে যদিও আপনার এককর্নিংয়ের মানদণ্ডটি এক জায়গায় রয়েছে তবে এটি আবদ্ধ রয়েছে, তাই আপনার কলারদের কেন তাদের ইউনিকর্নের দরকার আছে তা নিয়ে ধারণা করা উচিত (আমি আজকের দিনের স্যুপ অর্ডার দিয়ে ক্ল্যাম চাওডার পেতে পারি, তবে তা না করে ' t মানে আমি একই কাজটি করে আগামীকাল তা পেয়ে যাব)। এছাড়াও, আপনাকে একটি শিংয়ের জন্য একটি ডিফল্ট মান প্রকাশ করতে হবে Horse। যদি Unicornএটি নিজস্ব ধরনের হয় তবে আপনাকে একটি নতুন টাইপ তৈরি করতে হবে এবং টাইপ ম্যাপিংগুলি বজায় রাখতে হবে, যা ওভারহেড প্রবর্তন করতে পারে।
moarboilerplate

1
@ মোবারবাইলারপ্লেট: আমরা সমাধানটিকে সমর্থনকারী সবাইকে বিবেচনা করি। সৌন্দর্যের অংশটি হ'ল এটি ইউনিকর্নের কোনও বাস্তবায়ন বিশদ থেকে স্বাধীন। আপনি কোনও ডেটা সদস্য, শ্রেণি বা দিনের সময়ের ভিত্তিতে বৈষম্যহীন কিনা (সেই ঘোড়াগুলি মধ্যরাত্রে চাঁদগুলিতে পরিণত হয়ে উঠতে পারে যদি আমি জানি সকলের জন্য চাঁদ ঠিক থাকে), সমাধানটি দাঁড়িয়েছে, ইন্টারফেসটি একই থাকবে।
মার্টিন মাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.