অপরিবর্তনীয় বস্তু ব্যবহার করার সময় বেশিরভাগ মুরগি-ও ডিমের সমস্যা সমাধানের জন্য কি একটি নির্দিষ্ট নকশার কৌশল প্রয়োগ করা যেতে পারে?


17

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

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

[সম্পাদনা] সমস্ত উপাদান উদাহরণ "সিঙ্গলটন", জাভা এনামের মতো।

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

এই সমস্যাটি সমাধান করার জন্য কি তাদের কোনও উপায় নেই, বা সমস্যা সমাধানের জন্য আমার কি "ক্রিয়ামূলক" প্রোগ্রামিং কৌশল বা অন্য কোনও প্যাটার্ন ব্যবহার করা দরকার?


2
আমার কাছে, আপনি যেভাবে বলছেন, সেখানে জল নেই বরফও নেই। এখানে কেবল h2oউপাদান রয়েছে
12:11

1
আমি জানি এটি আরও "বৈজ্ঞানিক জ্ঞান" তৈরি করবে, তবে একটি খেলায় প্রসঙ্গের উপর নির্ভর করে "পরিবর্তনশীল" বৈশিষ্ট্যযুক্ত একটি উপাদানের পরিবর্তে "স্থির" বৈশিষ্ট্যযুক্ত দুটি পৃথক উপাদান হিসাবে এটি মডেল করা আরও সহজ।
সেবাস্তিয়ান ডিয়ট

সিঙ্গলটন একটি বোবা ধারণা।
ডেডজিমি

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

এই অন্যান্য প্রশ্নের উত্তরটি আমার সন্দেহের সত্যতা নিশ্চিত করেছে যে পরিবর্তনগুলি দিয়ে জিনিসগুলি খুব দ্রুত জটিল হয়ে
80৮০৫৮/২

উত্তর:


2

সমাধানটি কিছুটা ঠকাই। বিশেষ করে:

  • এ তৈরি করুন, তবে বি এর অবিশ্বাস্য রেফারেন্সটি ছেড়ে যান (কেননা বি এখনও বিদ্যমান নেই)।

  • বি তৈরি করুন এবং এটিকে নির্দেশ করুন A.

  • বি এ নির্দেশ করতে A আপডেট করুন এর পরে A বা B কে আপডেট করবেন না।

এটি হয় স্পষ্টভাবে করা যেতে পারে (উদাহরণস্বরূপ সি ++):

struct List {
    int n;
    List *next;

    List(int n, List *next)
        : n(n), next(next);
};

// Return a list containing [0,1,0,1,...].
List *binary(void)
{
    List *a = new List(0, NULL);
    List *b = new List(1, a);
    a->next = b; // Evil, but necessary.
    return a;
}

বা স্পষ্টভাবে (উদাহরণস্বরূপ হাস্কেল):

binary :: [Int]
binary = a where
    a = 0 : b
    b = 1 : a

পারস্পরিক নির্ভরশীল অবিচ্ছেদ্য মানগুলির মায়া অর্জনের জন্য হাস্কেল উদাহরণ অলস মূল্যায়ন ব্যবহার করে। মানগুলি শুরু হয়:

a = 0 : <thunk>
b = 1 : a

aএবং bউভয়ই স্বাধীনভাবে বৈধ হেড-স্বাভাবিক ফর্ম । প্রতিটি কনস অন্যান্য ভেরিয়েবলের চূড়ান্ত মান প্রয়োজন ছাড়াই নির্মিত যেতে পারে। যখন থাঙ্কটি মূল্যায়ন করা হয়, তখন এটি একই ডাটা bপয়েন্টগুলিতে নির্দেশ করবে।

সুতরাং, যদি আপনি দুটি অপরিবর্তনীয় মান একে অপরের প্রতি নির্দেশ করতে চান তবে আপনাকে হয় দ্বিতীয়টি তৈরির পরে প্রথমটি আপডেট করতে হবে, বা এটি করার জন্য একটি উচ্চ-স্তরের প্রক্রিয়া ব্যবহার করতে হবে।


আপনার বিশেষ উদাহরণে, আমি সম্ভবত এটি হাস্কেলের মধ্যে প্রকাশ করতে পারি:

data Material = Water {temperature :: Double}
              | Ice   {temperature :: Double}

setTemperature :: Double -> Material -> Material
setTemperature newTemp (Water _) | newTemp <= 0.0 = Ice newTemp
                                 | otherwise      = Water newTemp
setTemperature newTemp (Ice _)   | newTemp >= 1.0 = Water newTemp
                                 | otherwise      = Ice newTemp

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


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

6

আপনার উদাহরণস্বরূপ, আপনি কোনও সামগ্রীতে একটি রূপান্তর প্রয়োগ করছেন যাতে আমি বর্তমান ApplyTransform()পদ্ধতির BlockBaseপরিবর্তনের চেষ্টা করার পরিবর্তে কোনও পদ্ধতির মতো কিছু ব্যবহার করব ।

উদাহরণস্বরূপ, কিছু তাপ প্রয়োগ করে একটি জলব্লককে আইসব্লক পরিবর্তন করতে, আমি এর মতো কিছু কল করব

BlockBase currentBlock = new IceBlock();
currentBlock = currentBlock.ApplyTemperature(1); 
// currentBlock is now a WaterBlock 

এবং IceBlock.ApplyTemperature()পদ্ধতিটি এরকম কিছু দেখাচ্ছে:

public class IceBlock() : BlockBase
{
    public BlockBase ApplyTemperature(int temp)
    {
        return (temp > 0 ? new WaterBlock((BlockBase)this) : this);
    }
}

এটি একটি উত্তরের উত্তর, তবে দুর্ভাগ্যক্রমে কেবল কারণ আমি উল্লেখ করতে ব্যর্থ হয়েছি যে আমার "উপকরণ", প্রকৃতপক্ষে আমার "ব্লকগুলি" সমস্ত সিঙ্গলটন, সুতরাং নতুন ওয়াটারব্লক () কেবল কোনও বিকল্প নয়। এটাই হ'ল অপরিবর্তনীয় মূল সুবিধা, আপনি এগুলিকে অসীম ব্যবহার করতে পারেন। র্যামে 500,000 ব্লক থাকার পরিবর্তে আমার 100 টি ব্লকের 500,000 উল্লেখ রয়েছে। অনেক সস্তা!
সেবাস্তিয়ান ডিয়ট

সুতরাং BlockList.WaterBlockনতুন ব্লক তৈরির পরিবর্তে ফিরে কী হবে?
রাহেল

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

@ সেবাস্তিয়ান আমি ভাবছি যে BlockListএটি কেবলমাত্র একটি staticশ্রেণি যা প্রতিটি ব্লকের একক দৃষ্টান্তের জন্য দায়ী, সুতরাং আপনার কোনও দৃষ্টান্ত তৈরি করতে হবে না BlockList(আমি সি #
রাচেল

@ সেবাস্তেয়েন: আপনি যদি সিংজল্টন ব্যবহার করেন তবে আপনাকে মূল্য দিতে হবে।
ডেড এমএমজি

6

চক্র ভাঙ্গার আরেকটি উপায় হ'ল উপাদান এবং সংক্রমণ সম্পর্কে উদ্বেগকে আলাদা করা, কিছু কিছু তৈরি ভাষায়:

water = new Block("water");
ice = new Block("ice");

transitions = new Transitions([
    new transitions.temperature.Below(0.0, water, ice),
    new transitions.temperature.Above(0.0, ice, water),
]);

হু, প্রথমদিকে এটি পড়া আমার পক্ষে কঠিন ছিল, তবে আমি মনে করি এটি মূলত আমার একইরকম পন্থাটি সমর্থন করেছিল।
আইডান কুলি

1

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

data Material = Water | Ice

blockForTemperature :: Double -> Material
blockForTemperature x = 
  if x < 0 then Ice else Water

অথবা হতে পারে:

transitionForTemperature :: Material -> Double -> Material
transitionForTemperature oldMaterial newTemp = 
  case (oldMaterial, newTemp) of
    (Ice, _) | newTemp > 0 -> Water
    (Water, _) | newTemp <= 0 -> Ice

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


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