মোনাডস কি উত্তরাধিকারের শ্রেণিবিন্যাসের পক্ষে কার্যকর (সম্ভবত পছন্দসই) বিকল্প?


20

আমি এর আগে মনোদের একটি ভাষা-অজ্ঞাত বিবরণ ব্যবহার করতে যাচ্ছি , প্রথমে মনোয়েডগুলি বর্ণনা করে:

একটি মনোয়েড হ'ল (মোটামুটি) ফাংশনগুলির একটি সেট যা কিছু পরামিতি হিসাবে লাগে এবং একই ধরণের ফিরে আসে return

একটি মোনাড হ'ল (মোটামুটি) ফাংশনগুলির একটি সেট যা পরামিতি হিসাবে একটি মোড়কের ধরণ নেয় এবং একই মোড়কের প্রকারটি প্রদান করে।

সেগুলি সংজ্ঞা নয়, বর্ণনাকারী নোট করুন। এই বিবরণ আক্রমণ করতে নির্দ্বিধায়!

সুতরাং ওও ভাষায়, একটি মোনাড এই জাতীয় ক্রিয়াকলাপের অনুমতি দেয়:

Flier<Duck> m = new Flier<Duck>(duck).takeOff().flyAround().land()

নোট করুন যে মোনাড অন্তর্ভুক্ত শ্রেণীর চেয়ে বরং এই ক্রিয়াকলাপগুলির শব্দার্থককে সংজ্ঞায়িত করে এবং নিয়ন্ত্রণ করে।

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

কিন্তু তারপরে আমরা বিমানহীন পাখি নিয়ে সমস্যায় পড়ি, কারণ penguin.takeOff()ব্যর্থ হয়। আমাদের এক্সেকশন থ্রো এবং হ্যান্ডলিংয়ের অবলম্বন করতে হবে।

এছাড়াও, একবার আমরা বলি যে পেঙ্গুইন হ'ল Birdএকাধিক উত্তরাধিকার নিয়ে আমরা সমস্যায় পড়ি, উদাহরণস্বরূপ যদি আমাদেরও বংশগতি থাকে Swimmer

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

সুতরাং এই ক্ষেত্রে, আমরা Flier<T>উপরের উদাহরণের মতো একটি মোনাদ চাই:

Flier<Duck> m = new Flier<Duck>(duck).takeOff().flyAround().land()

... এবং আমরা একটি instantiate না হবে Flier<Penguin>। এমনকি এটি সংঘটন থেকে রোধ করতে আমরা স্থির টাইপিং ব্যবহার করতে পারি, সম্ভবত কোনও মার্ক ইন্টারফেস দিয়ে। বা রানটাইম সক্ষমতা-চেকিং জামিন আউট। তবে সত্যই, কোনও প্রোগ্রামারকে কখনও পেয়ারগুইন ফ্লেয়ারে ফেলা উচিত নয়, একই অর্থে তাদের কখনই শূন্য দ্বারা ভাগ করা উচিত নয়।

এছাড়াও, এটি আরও সাধারণভাবে প্রযোজ্য। একটি ফ্লাইয়ার পাখি হতে হবে না। উদাহরণস্বরূপ Flier<Pterodactyl>, বা Flier<Squirrel>those স্বতন্ত্র প্রকারের শব্দার্থবিজ্ঞান পরিবর্তন না করে।

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

সুতরাং আমার প্রশ্নটি হ'ল যেভাবে আমরা উত্তরাধিকারের তুলনায় রচনার পক্ষে এসেছি, তাও উত্তরাধিকারের চেয়ে মনদের পক্ষে যাওয়ার পক্ষে কি বুদ্ধি রয়েছে?

(বিটিডাব্লু আমি নিশ্চিত ছিলাম না এটি এখানে বা কমপ সায়িতে হওয়া উচিত কিনা তবে এটি বাস্তবের মডেলিংয়ের মতো সমস্যা বলে মনে হয় But তবে সম্ভবত এটি আরও ভাল।


1
এটি কীভাবে কাজ করে তা আমি নিশ্চিত তা নিশ্চিত নয়: একটি কাঠবিড়ালি এবং হাঁস একইভাবে উড়ে না - সুতরাং "ফ্লাই অ্যাকশন" এই শ্রেণীর মধ্যে প্রয়োগ করা দরকার ... এবং কাঠের কাঠি ও হাঁস তৈরির জন্য ফ্লাইয়ারের একটি পদ্ধতি প্রয়োজন উড়ে ... সম্ভবত একটি সাধারণ ফ্লায়ার ইন্টারফেসে ... ওফস এক মিনিট অপেক্ষা করুন ... আমি কিছু মিস করেছি?
Assylias

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

3
আপনি কি জিজ্ঞাসার চেষ্টা করছেন যে প্যারামেট্রিক পলিমারফিজম ব্যবহার সবসময় সাব টাইপ পলিমॉर्फিজমের একটি কার্যকর বিকল্প?
কেসপ্যান্ডিয়ন

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

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

উত্তর:


15

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

আমি তাদের যতদূর বুঝতে পেরেছি, মনদেদের উত্তরাধিকারের সাথে মূলত কিছুই করার নেই। আমি বলব যে দুটি জিনিসই কম-বেশি orthogonal: এগুলি বিভিন্ন সমস্যা সমাধানের উদ্দেশ্যে এবং তাই:

  1. এগুলি কমপক্ষে দুটি ইন্দ্রিয়তে synergistically ব্যবহার করা যেতে পারে:
    • খুঁজে বার করো Typeclassopedia , যা হাস্কেলের ধরণের অনেক কভার করে। আপনি লক্ষ্য করবেন যে তাদের মধ্যে উত্তরাধিকারের মতো সম্পর্ক রয়েছে। উদাহরণস্বরূপ, মোনাদ অ্যাপ্লিকটিভ থেকে উত্পন্ন, যা নিজেই ফান্টকার থেকে উত্পন্ন।
    • মোনাডসের উদাহরণস্বরূপ ডেটা ধরণের শ্রেণিবিন্যাসে অংশ নিতে পারে। মনে রাখবেন, মোনাড আরও ইন্টারফেসের মতো - একটি নির্দিষ্ট ধরণের জন্য এটি প্রয়োগ করা আপনাকে ডেটা টাইপ সম্পর্কে কিছু জিনিস বলে, তবে সব কিছু নয়।
  2. অন্যটির জন্য একটি ব্যবহার করার চেষ্টা করা কঠিন এবং কুশ্রী হয়ে উঠবে।

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


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

  1. একটি মোনাড হ'ল ফাংশনগুলির একটি সেট যা একটি ধারক প্রকারটিকে প্যারামিটার হিসাবে গ্রহণ করে এবং একই ধারক প্রকারটি প্রদান করে।

    না, এই হল Monadমধ্যে Haskell: একটি স্থিতিমাপ টাইপ m aএকজন বাস্তবায়ন return :: a -> m aএবং (>>=) :: m a -> (a -> m b) -> m b, নিম্নলিখিত আইন পরিতৃপ্ত:

    return a >>= k  ==  k a
    m >>= return  ==  m
    m >>= (\x -> k x >>= h)  ==  (m >>= k) >>= h
    

    মোনাডের কয়েকটি উদাহরণ রয়েছে যা কনটেইনার নয় ( (->) b), এবং এমন কিছু পাত্রে রয়েছে যা মনোদের উদাহরণ (এবং তৈরি করা যায় না) উদাহরণস্বরূপ Setশ্রেণীর সীমাবদ্ধতার কারণে)। সুতরাং "ধারক" স্বজ্ঞাততা একটি দুর্বল। দেখুন এই আরো উদাহরণ জন্য।

  2. সুতরাং ওও ভাষায়, একটি মোনাড এই জাতীয় ক্রিয়াকলাপের অনুমতি দেয়:

      Flier<Duck> m = new Flier<Duck>(duck).takeOff().flyAround().land()
    

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

    Flier<Duck> m = land(flyAround(takeOff(new Flier<Duck>(duck))));
    

    আমি বিশ্বাস করি এটি একটি "সাবলীল ইন্টারফেস" বা "পদ্ধতি চেইনিং" হিসাবে পরিচিত (তবে আমি নিশ্চিত নই) pattern

  3. নোট করুন যে মোনাড অন্তর্ভুক্ত শ্রেণীর চেয়ে বরং এই ক্রিয়াকলাপগুলির শব্দার্থককে সংজ্ঞায়িত করে এবং নিয়ন্ত্রণ করে।

    যে ডেটা টাইপগুলি মনডও হয় (এবং প্রায় সবসময়!) এমন অপারেশন করতে পারে যা মনাদের সাথে সম্পর্কিত নয়। এখানে তিনটি ফাংশনের সমন্বয়ে একটি হাস্কেল উদাহরণ রয়েছে যার উপর []মনাদের সাথে কিছুই করার নেই: []"অপারেশনটির শব্দার্থকে সংজ্ঞায়িত করে এবং নিয়ন্ত্রণ করে" এবং "অন্তর্ভুক্ত শ্রেণি" দেয় না, তবে এটি একটি মোনাড তৈরি করার পক্ষে পর্যাপ্ত নয়:

    \predicate -> length . filter predicate . reverse
    
  4. আপনি সঠিকভাবে উল্লেখ করেছেন যে জিনিসগুলিকে মডেল করতে শ্রেণিবদ্ধ শ্রেণিবদ্ধ ব্যবহার করতে সমস্যা রয়েছে। যাইহোক, আপনার উদাহরণগুলি এমন কোনও প্রমাণ উপস্থাপন করে না যা সোনাদারা করতে পারে:

    • উত্তরাধিকার ভাল যে স্টাফ একটি ভাল কাজ করুন
    • উত্তরাধিকার খারাপ যে স্টাফ একটি ভাল কাজ করুন

3
ধন্যবাদ! আমার প্রক্রিয়া করার জন্য প্রচুর। আমার খারাপ লাগছে না - আমি অন্তর্দৃষ্টিটির প্রশংসা করি। আমি খারাপ ধারণার আশেপাশে আরও খারাপ অনুভব করব। :) (স্ট্যাকেক্সচেঞ্জের পুরো পয়েন্টে যায়!)
রব

1
@ রবি আপনাকে স্বাগতম! যাইহোক, আপনি যদি এর আগে এটি না শুনে থাকেন তবে আমি LYAH কে সুপারিশ করি এটি মনড (এবং হাস্কেল!) শেখার জন্য একটি দুর্দান্ত উত্স কারণ এটির প্রচুর উদাহরণ রয়েছে (এবং আমি অনুভব করি যে কয়েক হাজার উদাহরণ করা ভাল উপায় হ'ল মোকাবেলা)।

এখানে প্রচুর আছে; আমি মন্তব্যগুলিকে সোয়াম করতে চাই না, তবে কয়েকটি মন্তব্য: # 2 land(flyAround(takeOff(new Flier<Duck>(duck))))কাজ করে না (কমপক্ষে ওওতে) কারণ এই নির্মাণের জন্য ফ্লেয়ারের বিশদ পাওয়ার জন্য এনক্যাপসুলেশন ব্রেকিং প্রয়োজন। ক্লাসে opertions শৃঙ্খলাবদ্ধ করে, ফ্লায়ারের বিবরণ গোপন থাকে এবং এটি এর শব্দার্থবিজ্ঞান সংরক্ষণ করতে পারে। সেই কারনেই অনুরূপ যে মধ্যে Haskell একটি একসংখ্যা শুশ্রূষা হয় (a, M b)এবং (M a, M b)যাতে একসংখ্যা "ACTION" ফাংশন তার রাষ্ট্র তা প্রকাশ করার নেই।
রব

# 1, দুর্ভাগ্যক্রমে আমি হাসকেলে মোনাডের কঠোর সংজ্ঞাটি ঝাপসা করার চেষ্টা করছি , কারণ হাস্কেলকে যেকোন কিছু ম্যাপিংয়ে একটি বড় সমস্যা রয়েছে: কনস্ট্রাক্টরগুলির রচনা সহ ফাংশন রচনা, যা আপনি জাভার মতো পথচারী ভাষায় সহজেই করতে পারবেন না। সুতরাং unitঅন্তর্ভুক্ত ধরণের উপর (বেশিরভাগ) কনস্ট্রাক্টর bindহয়ে যায় এবং (বেশিরভাগ ক্ষেত্রে) একটি অন্তর্নিহিত সংকলিত সময় অপারেশন হয়ে যায় (অর্থাত্ প্রথম দিকের বাইন্ডিং) যা ক্লাসের সাথে "ক্রিয়া" ফাংশনকে যুক্ত করে। আপনার যদি প্রথম শ্রেণীর ফাংশন, বা কোনও ফাংশন <ক, মোনাড <বি>> শ্রেণি থাকে তবে কোনও bindপদ্ধতি দেরীতে বাইন্ডিং করতে পারে, তবে আমি সেই অপব্যবহারটি পরে নিয়ে যাব। ;)
রব

# 3 সম্মত হন, এবং এটি এটির সৌন্দর্য। যদি Flier<Thing>বিমানের শব্দার্থবিদ্যা নিয়ন্ত্রণ করে, তবে এটি প্রচুর পরিমাণে ডেটা এবং ক্রিয়াকলাপ প্রকাশ করতে পারে যা ফ্লাইট সিমানটিকগুলি বজায় রাখে, যখন "মোনাড" - স্পেসিফিক সিমানটিকস এটি কেবল শৃঙ্খলাবদ্ধ এবং এনক্যাপসুলেটেড তৈরির বিষয়ে। এই উদ্বেগগুলি (এবং আমি যাদের ব্যবহার করছি তাদের সাথে না) Resource<String>মোনাদের অভ্যন্তরের শ্রেণীর উদ্বেগগুলি নাও পারে: উদাহরণস্বরূপ একটি httpStatus সম্পত্তি রয়েছে, তবে স্ট্রিং এর নেই।
রব

1

সুতরাং আমার প্রশ্নটি হ'ল যেভাবে আমরা উত্তরাধিকারের তুলনায় রচনার পক্ষে এসেছি, তাও উত্তরাধিকারের চেয়ে মনদের পক্ষে যাওয়ার পক্ষে কি বুদ্ধি রয়েছে?

অ-ওও ভাষায়, হ্যাঁ। আরও প্রচলিত ওও ভাষাগুলিতে, আমি না বলব say

সমস্যাটি হ'ল বেশিরভাগ ভাষায় টাইপ স্পেশালাইজেশন থাকে না, যার অর্থ আপনি তৈরি করতে পারবেন না Flier<Squirrel>এবং Flier<Bird>বিভিন্ন প্রয়োগও করতে পারেন। আপনাকে কিছু করতে হবে static Flier Flier::Create(Squirrel)(এবং তারপরে প্রতিটি ধরণের জন্য ওভারলোড)। যার পরিবর্তে আপনি যখনই কোনও নতুন প্রাণী যুক্ত করবেন তখন আপনাকে এই ধরণের সংশোধন করতে হবে এবং সম্ভবত এটির কাজটি করার জন্য কোডের বেশ কিছুটা নকল করতে হবে।

ওহ, এবং কয়েকটি ভাষায় নয় (উদাহরণস্বরূপ সি #) public class Flier<T> : T {}অবৈধ। এটি এমনকি নির্মাণ করবে না। বেশিরভাগ, না সমস্ত ওও প্রোগ্রামাররা Flier<Bird>এখনও একটি হওয়ার আশা করে Bird


মন্তব্যের জন্য ধন্যবাদ. আমার আরও কিছু চিন্তাভাবনা আছে, তবে কেবল তুচ্ছভাবে, Flier<Bird>প্যারামিটারাইজড ধারক হলেও কেউ এটিকে Bird(!) List<String>তালিকা হিসাবে স্ট্রিং হিসাবে বিবেচনা করবে না।
রব

@RobY - Flierনয় শুধু একটি ধারক। আপনি যদি এটিকে কেবল একটি ধারক হিসাবে বিবেচনা করেন তবে কেন আপনি কখনও ভাবেন যে এটি উত্তরাধিকারের ব্যবহার প্রতিস্থাপন করতে পারে?
তেলস্তিন

আমি তোমাকে সেখানে হারিয়েছি ... আমার বক্তব্যটি হ'ল মোনাড একটি উন্নত ধারক। Animal / Bird / Penguinএটি সাধারণত একটি খারাপ উদাহরণ, কারণ এটি শব্দার্থবিজ্ঞানের সমস্ত ধরণের আনে। একটি ব্যবহারিক উদাহরণ হ'ল আমরা ব্যবহার করছি একটি রেস্ট-ইশ মোনাড: এর Resource<String>.from(uri).get() Resourceউপরে String(বা অন্য কোনও ধরণের) শব্দার্থবিজ্ঞান যুক্ত করা হয়েছে , সুতরাং এটি সম্ভবত একটি নয় String
রব

@ রবি - তবে এটি কোনওভাবেই উত্তরাধিকারের সাথে সম্পর্কিত নয়।
তেলস্তিন

এটি ভিন্ন ধরণের সংযোজন ব্যতীত। আমি স্ট্রিংটিকে রিসোর্সে রাখতে পারি, বা আমি একটি রিসোর্সস্ট্রিং ক্লাসটি বিমূর্ত করতে পারি এবং উত্তরাধিকার ব্যবহার করতে পারি। আমার ধারণা হ'ল চেইন কনটেইনারে ক্লাস স্থাপন করাকে উত্তরাধিকারের সাথে শ্রেণিক শ্রেণিবিন্যাসে রাখার চেয়ে বিমূর্ত আচরণের একটি ভাল উপায়। সুতরাং "প্রতিস্থাপন / অবজ্ঞা" অর্থে "কোনওভাবে সম্পর্কিত নয়" - হ্যাঁ।
রব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.