নিজে বা অন্য দুটি জিনিস উপস্থাপন করে এমন কোনও কিছুর জন্য কীভাবে ডেটাটাইপ তৈরি করবেন


16

পটভূমি

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

তাস

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

interface Card {
    String name();
    String text();
    // etc
}

এখানে দুটি সাবক্লাস রয়েছে Card, যা আমি কল করছি PartialCard(দুই অংশের কার্ডের অর্ধেক) এবং WholeCard(একটি নিয়মিত কার্ড)। PartialCardদুটি অতিরিক্ত পদ্ধতি রয়েছে: PartialCard otherPart()এবং boolean isFirstPart()

প্রতিনিধিরা

যদি আমি একটি ডেক আছে, এটা গঠিত উচিত WholeCardগুলি, না Card, গুলি একটি Cardএকটি হতে পারে PartialCard, এবং যে অর্থে দেখা যায় না। সুতরাং আমি এমন একটি বস্তু চাই যা একটি "শারীরিক কার্ড" উপস্থাপন করে, এটি এমন একটি জিনিস যা একটি WholeCard, বা দুটি PartialCardগুলি প্রতিনিধিত্ব করতে পারে । আমি অস্থায়ীভাবে এই ধরণের কল করছি Representativeএবং Cardপদ্ধতিটি থাকবে getRepresentative()। এ Representativeএটি প্রতিনিধিত্ব করে এমন কার্ড (গুলি) সম্পর্কে প্রায় কোনও সরাসরি তথ্য সরবরাহ করবে না, এটি কেবল এটি / তাদেরকে নির্দেশ করবে। এখন আমার উজ্জ্বল / পাগল / মূক ধারণা (আপনি সিদ্ধান্ত নিতে) থেকে যে WholeCard উত্তরাধিকারী হয় উভয় Card এবং Representative। সর্বোপরি, তারা কার্ড যা নিজের প্রতিনিধিত্ব করে! হোলকার্ডগুলি getRepresentativeহিসাবে বাস্তবায়ন করতে পারে return this;

হিসাবে PartialCards, তারা নিজের প্রতিনিধিত্ব করে না, তবে তাদের একটি বাহ্যিক রয়েছে Representativeযা একটি নয় Card, তবে দুটি এসকে অ্যাক্সেসের জন্য পদ্ধতি সরবরাহ করে PartialCard

আমি মনে করি এই ধরণের শ্রেণিবিন্যাসটি বোধগম্য হয় তবে এটি জটিল। আমরা যদি Card"ধারণাগত কার্ড" এবং Representativeএসকে "শারীরিক কার্ড " হিসাবে ভাবি তবে বেশিরভাগ কার্ড উভয়ই! আমি মনে করি আপনি একটি যুক্তি দিতে পারেন যে শারীরিক কার্ডগুলিতে বাস্তবে ধারণাগত কার্ড থাকে এবং তারা একই জিনিস নয় তবে আমি যুক্তি দিয়ে বলব যে তারা they

টাইপ-ingালাইয়ের প্রয়োজনীয়তা

কারণ PartialCardWholeCardsউভয়ই উভয় এবং এগুলি Cardআলাদা করার জন্য সাধারণত কোনও ভাল কারণ নেই, আমি সাধারণত কাজ করে যাচ্ছিলাম Collection<Card>। তাই কখনও কখনও PartialCardতাদের অতিরিক্ত পদ্ধতিগুলি অ্যাক্সেস করার জন্য আমার প্রয়োজন হয় cast এই মুহুর্তে, আমি এখানে বর্ণিত সিস্টেমটি ব্যবহার করছি কারণ আমি সত্যিই সুস্পষ্ট ক্যাসেট পছন্দ করি না। এবং এর মতো Card, তারা যেগুলির প্রকৃত প্রতিনিধিত্ব করে সেটি অ্যাক্সেস করার জন্য Representativeএকটি WholeCardবা কাস্ট করা প্রয়োজন ।CompositeCard

সুতরাং কেবল সংক্ষিপ্তসার জন্য:

  • বেস টাইপ Representative
  • বেস টাইপ Card
  • টাইপ করুন WholeCard extends Card, Representative(কোনও অ্যাক্সেসের প্রয়োজন নেই, এটি নিজের প্রতিনিধিত্ব করে)
  • প্রকার PartialCard extends Card(অন্যান্য অংশে অ্যাক্সেস দেয়)
  • প্রকার Composite extends Representative(উভয় অংশে অ্যাক্সেস দেয়)

এ কি পাগল? আমি মনে করি এটি আসলে অনেক অর্থবোধ করে, তবে আমি সত্যই নিশ্চিত নই।


1
পার্টিশালকার্ডগুলি কি কার্যকরভাবে কার্ডগুলি ব্যতীত শারীরিক কার্ডের জন্য দুটি আছে? তারা যে ক্রমটি খেলেছে তা কি ব্যাপার? আপনি কি কেবল "ডেক স্লট" এবং "হোলকার্ড" ক্লাস তৈরি করতে এবং ডেকস্লটকে একাধিক হোলকার্ড করার অনুমতি দিতে পারবেন না, এবং তারপরে ডেকস্লট.হোলকার্ডস.প্লে এর মতো কিছু করতে পারেন এবং যদি সেখানে 1 বা 2 উভয়ই খেলেন যেন তারা আলাদা তাস? মনে হচ্ছে এটি আপনার জটিল ডিজাইনের সাথে মনে হচ্ছে এমন কিছু আছে যা আমি মিস করছি :)
এন্ডারল্যান্ড

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

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

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

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

উত্তর:


14

আমার কাছে মনে হচ্ছে আপনার মতো ক্লাস করা উচিত

class PhysicalCard {
    List<LogicalCard> getLogicalCards();
}

শারীরিক কার্ডের সাথে সম্পর্কিত কোডটি শারীরিক কার্ড শ্রেণীর সাথে ডিল করতে পারে এবং লজিকাল কার্ডের সাথে সম্পর্কিত কোডটি এটি মোকাবেলা করতে পারে।

আমি মনে করি আপনি একটি যুক্তি তৈরি করতে পারেন যে শারীরিক কার্ডগুলিতে বাস্তবে ধারণাগত কার্ড থাকে এবং তারা একই জিনিস নয়, তবে আমি যুক্তি দেব যে তারা they

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


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

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

8

কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় কথায় আমি প্রস্তাবিত সমাধানটি খুব সীমিত এবং শারীরিক বাস্তবতা থেকে স্বল্প ও সংক্ষিপ্ত এবং মডেল হ'ল সামান্য সুবিধা নিয়ে।

আমি দুটি বিকল্পের মধ্যে একটির পরামর্শ দেব:

বিকল্প 1. এটি এমটিজি সাইটের ওয়্যার // টিয়ার তালিকার মতো হাফ এ // হাফ বি হিসাবে চিহ্নিত সিঙ্গল কার্ড হিসাবে বিবেচনা করুন । তবে, আপনার সত্তাকে প্রতিটি বৈশিষ্ট্যের এন অন্তর্ভুক্ত করার অনুমতি দিন : প্লেযোগ্য-নাম, মান ব্যয়, প্রকার, বিরলতা, পাঠ্য, প্রভাব ইত্যাদি ..Card

interface Card {
  List<String> Names();
  List<ManaCost> Costs();
  List<CardTypes> Types();
  /* etc. */
}

অপশন ২. বিকল্প 1 এর চেয়ে আলাদা নয়, শারীরিক বাস্তবতার পরে এটিকে মডেল করুন। আপনার একটি Cardসত্তা রয়েছে যা একটি শারীরিক কার্ড উপস্থাপন করে । এবং, এর উদ্দেশ্য তখন এন Playable জিনিস রাখা hold সেই Playable'র প্রতিটি একটি স্বতন্ত্র নাম, ক্ষমতা খরচ, প্রভাব তালিকা, ক্ষমতার তালিকা, ইত্যাদি থাকতে পারে .. আর তোমার "প্রকৃত" Cardনিজস্ব আইডেন্টিফায়ার (অথবা নাম) থাকতে পারে প্রতিটি একটি যৌগ যে Playable' নাম গুলি, অনেক মত এমটিজি ডাটাবেস করতে দেখা যাচ্ছে।

interface Card {
  String Name();
  List<Playable> Playables();
}

interface Playable {
  String Name();
  ManaCost Cost();
  CardType Type();
  /* etc. */
}

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


5

এই বিষয়গুলির উদ্দেশ্যটি কেবলমাত্র কার্ডের বৈশিষ্ট্য ধরে রাখা। তারা সত্যই নিজেরাই কিছু করে না।

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

সর্বোপরি, তারা কার্ড যা নিজের প্রতিনিধিত্ব করে!

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

আমি যাদু সম্পর্কে কিছুই জানি না : জমায়েত , তবে আমি অনুমান করি যে আপনি আপনার কার্ডগুলি একইভাবে ব্যবহার করতে চান, তাদের আসল কাঠামো যাই হোক না কেন: আপনি একটি স্ট্রিং প্রতিনিধিত্ব প্রদর্শন করতে চান, আপনি আক্রমণটির মান গণনা করতে চান ইত্যাদি want

আপনি যে সমস্যার বর্ণনা করছেন তার জন্য, আমি এই ডিজি আরও সাধারণ সমস্যা সমাধানের জন্য সাধারণত উপস্থাপন করা সত্ত্বেও একটি কমপোজিট ডিজাইনের প্যাটার্ন সুপারিশ করব :

  1. একটি Cardইন্টারফেস তৈরি করুন , যেমন আপনি ইতিমধ্যে করেছেন।
  2. এমন একটি তৈরি করুন ConcreteCard, যা Cardএকটি সাধারণ ফেস কার্ড প্রয়োগ এবং সংজ্ঞা দেয়। এই ক্লাসে একটি সাধারণ কার্ডের আচরণ রাখতে দ্বিধা করবেন না ।
  3. একটি তৈরি করুন CompositeCard, যা প্রয়োগ করে Cardএবং আরও দুটি অতিরিক্ত (এবং একটি প্রাইমারী বেসরকারী) রয়েছে Card। তাদের কল করুন leftCardএবং rightCard

পদ্ধতির কমনীয়তা হ'ল CompositeCardএকটিতে দুটি কার্ড থাকে যা তারা নিজেরাই কংক্রিটকার্ড বা কমপোজিটকার্ড হতে পারে। আপনার গেমটিতে, leftCardএবং rightCardসম্ভবত পদ্ধতিগতভাবে এটি হবে ConcreteCardতবে ডিজাইন প্যাটার্ন আপনাকে চাইলে বিনামূল্যে উচ্চ স্তরের রচনাগুলি ডিজাইনের অনুমতি দেয়। আপনার কার্ডের কারসাজি আপনার কার্ডের আসল ধরণের বিষয়টি বিবেচনায় নেবে না এবং তাই আপনার সাবক্লাসে কাস্টিংয়ের মতো জিনিসগুলির প্রয়োজন নেই।

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

public class CompositeCard implements Card
{ 
   private final Card leftCard, rightCard;
   private final double factor;

   @Override // Defined in Card
   public double attack(Player p){
      return factor * (leftCard.attack(p) + rightCard.attack(p));
   }

   @Override // idem
   public String name()
   {
       return leftCard.name() + " combined with " + rightCard.name();
   }

   ...
}

এটি করার মাধ্যমে, আপনি যে কোনওর CompositeCardজন্য যেমন করেন ঠিক তেমন ব্যবহার করতে পারেন Cardএবং নির্দিষ্ট আচরণটি বহুবর্ষের জন্য লুকিয়ে থাকা ধন্যবাদ thanks

আপনি যদি নিশ্চিত হন CompositeCardযে একটিতে সর্বদা দুটি স্বাভাবিক থাকে তবে Cardআপনি ধারণাটি রাখতে পারেন এবং কেবল এবং এর ConcreateCardজন্য টাইপ হিসাবে ব্যবহার করতে পারেন । leftCardrightCard


আপনি সম্মিলিত প্যাটার্ন সম্পর্কে কথা বলছেন , তবে বাস্তবে যেহেতু আপনার Cardমধ্যে দুটি রেফারেন্স রয়েছে আপনি ডেকরেটার প্যাটার্নটিCompositeCard বাস্তবায়ন করছেন । আমি এই সমাধানটি ব্যবহার করতে ওপিকে পুনঃসামন্ডণও জানাই, ডেকোরেটর যাওয়ার উপায়!
স্পটড

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

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

@ কেভিন ক্রামউইড যতক্ষণ CompositeCardনা অতিরিক্ত পদ্ধতি প্রকাশ করে না, CompositeCardকেবলমাত্র একটি সাজসজ্জাবিদ।
স্পট করেছেন

"... ডিজাইনের প্যাটার্ন আপনাকে বিনামূল্যে উচ্চ স্তরের রচনাগুলি ডিজাইনের অনুমতি দেয়" - না, এটি নিখরচায় আসে না , কেবল বিপরীতে - এটি এমন একটি সমাধানের দামের জন্য আসে যা প্রয়োজনীয়তার জন্য প্রয়োজনের চেয়ে জটিল।
ডক ব্রাউন

3

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

সম্ভবত কার্ড এবং প্লেযোগ্য এর একটি প্রভাব আছে।


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

আহ ঠিক আছে. আপনার সমস্যার সাথে খুব প্রাসঙ্গিক নয়, তবে। আমি মুছে ফেলা উচিত?
ডেভিস্লোর

3

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

এর উচ্চতর বিমূর্ততা, একটি Cardইন্টারফেস দিয়ে শুরু করা যাক :

public interface Card {
    public void accept(CardVisitor visitor);
}

Cardইন্টারফেসে কিছুটা আরও আচরণ থাকতে পারে তবে বেশিরভাগ সম্পত্তি প্রাপ্তরা নতুন শ্রেণিতে চলে যায় CardProperties,:

public class CardProperties {
    // property methods, constructors, etc.

    String name();
    String text();
    // ...
}

এখন আমরা SimpleCardএকক সংখ্যক বৈশিষ্ট্য সহ একটি সম্পূর্ণ কার্ডের প্রতিনিধিত্ব করতে পারি :

public class SimpleCard implements Card {
    private CardProperties properties;

    // Constructors, ...

    @Override
    public void accept(CardVisitor visitor) {
        visitor.visit(properties);
    }
}

আমরা দেখতে পাই যে কীভাবে CardPropertiesএখনও CardVisitorঅবধি লিখিত লেখা শুরু হতে শুরু করে starting CompoundCardদুটি মুখের সাথে একটি কার্ড উপস্থাপনের জন্য আসুন :

public class CompoundCard implements Card {
    private CardProperties firstFaceProperties;
    private CardProperties secondFaceProperties;

    // Constructors, ...

    public void accept(CardVisitor visitor) {
        visitor.visit(firstFaceProperties, secondFaceProperties);
    }
}

CardVisitorউত্থান শুরু হয়। এখনই সেই ইন্টারফেসটি লেখার চেষ্টা করি:

public interface CardVisitor {
    public void visit(CardProperties properties);
    public void visit(CardProperties firstFaceProperties, CardProperties secondFaceProperties);
}

(এটি আপাতত ইন্টারফেসের প্রথম সংস্করণ We আমরা উন্নতি করতে পারি, যা পরে আলোচনা করা হবে))

আমরা এখন সমস্ত অংশ সরিয়ে ফেলেছি। আমাদের এখন কেবল তাদের একত্র করা দরকার:

List<Card> cards = new LinkedList<>();
cards.add(new SimpleCard(new CardProperties(/* ... */)));
cards.add(new CompoundCard(new CardProperties(/* ... */), new CardProperties(/* ... */)));

 for(Card card : cards) {
     card.accept(new CardVisitor() {
         @Override
         public void visit(CardProperties properties) {
             // Do something for simple cards with a single face
         }

         public void visit(CardProperties firstFaceProperties, CardProperties secondFaceProperties) {
             // Do something else for compound cards with two faces
         }
     });
 }

রানটাইমটি ভেঙে ফেলার চেষ্টা না করে পলিমারফিজমের মাধ্যমে#visit পদ্ধতির সঠিক সংস্করণে প্রেরণ পরিচালনা করবে।

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


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

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


1
আমি মনে করি এটি সহজেই অন্য ধরণের দুটি মুখোমুখী কার্ডে প্রসারিত হতে পারে (পাশাপাশি এবং পাশাপাশি পাশাপাশি ফিরেও করা যেতে পারে)। ++
রাবারডাক

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

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

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