किसी चीज़ के लिए डेटाटाइप कैसे बनाएं जो खुद या दो अन्य चीजों का प्रतिनिधित्व करता है


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()। A Representativeकार्ड पर लगभग कोई प्रत्यक्ष जानकारी प्रदान नहीं करेगा, जो इसका प्रतिनिधित्व करता है, यह केवल उसे / उन्हें इंगित करेगा। अब, मेरा शानदार / पागल / गूंगा विचार (आप तय करते हैं) यह है कि होलकार्ड दोनों से विरासत में मिले Cardऔर Representative। आखिरकार, वे कार्ड हैं जो खुद का प्रतिनिधित्व करते हैं! WholeCards के getRepresentativeरूप में लागू कर सकता है return this;

के रूप में PartialCards, वे खुद का प्रतिनिधित्व नहीं करते हैं, लेकिन उनके पास एक बाहरी है Representativeजो एक नहीं है Card, लेकिन दो PartialCardएस तक पहुंचने के लिए तरीके प्रदान करता है ।

मुझे लगता है कि इस प्रकार का पदानुक्रम समझ में आता है, लेकिन यह जटिल है। यदि हम Card"वैचारिक कार्ड" के रूप में सोचते हैं और Representative"भौतिक कार्ड" के रूप में, अच्छी तरह से, ज्यादातर कार्ड दोनों हैं! मुझे लगता है कि आप एक तर्क दे सकते हैं कि भौतिक कार्ड वास्तव में वैचारिक कार्ड होते हैं, और वे एक ही चीज नहीं हैं , लेकिन मैं तर्क दूंगा कि वे हैं।

टाइप-कास्टिंग की आवश्यकता

क्योंकि PartialCards और WholeCardsदोनों Cards हैं, और आमतौर पर उन्हें अलग करने का कोई अच्छा कारण नहीं है, मैं सामान्य रूप से बस काम करूंगा Collection<Card>। तो कभी-कभी मुझे PartialCardउनके अतिरिक्त तरीकों का उपयोग करने के लिए एस डालना होगा । अभी, मैं यहाँ वर्णित प्रणाली का उपयोग कर रहा हूँ क्योंकि मुझे स्पष्ट जातियाँ पसंद नहीं हैं। और जैसे Card, वास्तविक या वे प्रतिनिधित्व करने के लिए उपयोग करने के लिए या Representativeतो डाली जाएगी ।WholeCardCompositeCard

तो बस सारांश के लिए:

  • आधार प्रकार Representative
  • आधार प्रकार Card
  • प्रकार WholeCard extends Card, Representative(कोई पहुंच की आवश्यकता नहीं है, यह स्वयं का प्रतिनिधित्व करता है)
  • प्रकार PartialCard extends Card(अन्य भाग तक पहुँच देता है)
  • प्रकार Composite extends Representative(दोनों भागों तक पहुँच देता है)

क्या यह पागल है? मुझे लगता है कि यह वास्तव में बहुत मायने रखता है, लेकिन मुझे ईमानदारी से यकीन नहीं है।


1
क्या PartialCards प्रभावी रूप से कार्ड के अलावा अन्य दो भौतिक कार्ड हैं? क्या उनके द्वारा खेले गए आदेश में कोई फर्क है? क्या आप सिर्फ "डेक स्लॉट" और "होलकार्ड" क्लास नहीं बना सकते हैं और डेकसोलॉट्स को कई होलकार्ड्स की अनुमति दे सकते हैं, और उसके बाद ही डेकस्लोत.होलकार्ड्स की तरह कुछ करें। प्ले और अगर दोनों अलग-अलग हों तो दोनों 1 या 2 खेलते हैं। पत्ते? ऐसा लगता है कि आपके बहुत अधिक जटिल डिजाइन को देखते हुए कुछ ऐसा होना चाहिए जो मुझे याद आ रहा है :)
एंडरलैंड

मुझे वास्तव में ऐसा नहीं लगता कि मैं इस समस्या को हल करने के लिए पूरे कार्ड और आंशिक कार्ड के बीच बहुरूपता का उपयोग कर सकता हूं। हां, अगर मैं "प्ले" फ़ंक्शन चाहता था, तो मैं इसे आसानी से लागू कर सकता था, लेकिन समस्या आंशिक कार्ड है और पूरे कार्ड में अलग-अलग विशेषताओं के सेट हैं। मुझे वास्तव में इन वस्तुओं को देखने में सक्षम होना चाहिए कि वे क्या हैं, न कि उनके आधार वर्ग के रूप में। जब तक उस समस्या का कोई बेहतर समाधान न हो। लेकिन मैंने पाया है कि बहुरूपता उन प्रकारों के साथ अच्छी तरह से मिश्रण नहीं करता है जो एक सामान्य आधार वर्ग को साझा करते हैं, लेकिन उनके बीच अलग-अलग तरीके हैं, अगर यह समझ में आता है।
कोडब्रेकर

1
ईमानदारी से, मुझे लगता है कि यह हास्यास्पद रूप से जटिल है। आप केवल मॉडल लगते हैं "एक" रिश्ते, तंग युग्मन के साथ एक बहुत ही कठोर डिजाइन के लिए अग्रणी है। अधिक दिलचस्प यह होगा कि वे कार्ड वास्तव में क्या कर रहे हैं?
डेनियल जौर्स

2
यदि वे "सिर्फ डेटा ऑब्जेक्ट्स" हैं, तो मेरी वृत्ति में एक वर्ग होगा जिसमें दूसरी कक्षा की वस्तुओं की एक सरणी होती है, और इसे उस पर छोड़ दें; कोई विरासत या अन्य व्यर्थ जटिलताएँ नहीं। क्या उन दो वर्गों को PlayableCard और DrawableCard या WholeCard और CardPart होना चाहिए, मुझे पता नहीं है, क्योंकि मुझे लगभग इतना नहीं पता है कि आपका गेम कैसे काम करता है, लेकिन मुझे यकीन है कि आप उन्हें कॉल करने के लिए कुछ सोच सकते हैं।
इक्सेरे

1
उनके पास किस तरह के गुण हैं? क्या आप उन गुणों का उदाहरण दे सकते हैं जो इन गुणों का उपयोग करते हैं?
डैनियल जौर्स

जवाबों:


14

यह मुझे लगता है कि आपके पास एक वर्ग होना चाहिए

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

भौतिक कार्ड से संबंधित कोड भौतिक कार्ड वर्ग के साथ सौदा कर सकता है, और तार्किक कार्ड से संबंधित कोड उस से निपट सकता है।

मुझे लगता है कि आप एक तर्क दे सकते हैं कि भौतिक कार्ड वास्तव में वैचारिक कार्ड होते हैं, और वे एक ही चीज नहीं हैं, लेकिन मैं तर्क दूंगा कि वे हैं।

इससे कोई फर्क नहीं पड़ता कि आपको लगता है कि भौतिक और तर्क कार्ड एक ही बात है या नहीं। यह मत मानो कि सिर्फ इसलिए कि वे एक ही भौतिक वस्तु हैं, उन्हें आपके कोड में एक ही वस्तु होना चाहिए। क्या मायने रखता है कि क्या उस मॉडल को अपनाने से कोडर को पढ़ना और लिखना आसान हो जाता है। तथ्य यह है कि एक सरल मॉडल को अपनाना जहां हर भौतिक कार्ड को लगातार तार्किक कार्ड के संग्रह के रूप में माना जाता है, 100% समय, सरल कोड में परिणाम देगा।


2
अपवित्र क्योंकि यह सबसे अच्छा उत्तर है, हालांकि दिए गए कारण के लिए नहीं। यह सबसे अच्छा जवाब है क्योंकि यह सरल नहीं है, लेकिन क्योंकि भौतिक कार्ड और वैचारिक कार्ड एक ही बात नहीं हैं , और यह समाधान उनके रिश्ते को सही ढंग से प्रदर्शित करता है। यह सच है कि एक अच्छा ओओपी मॉडल हमेशा भौतिक वास्तविकता को प्रतिबिंबित नहीं करता है, लेकिन इसे हमेशा वैचारिक वास्तविकता को प्रतिबिंबित करना चाहिए। सादगी निश्चित रूप से अच्छी है, लेकिन यह वैचारिक शुद्धता के लिए एक सीट है।
केविन क्रुमविडे ने

2
@KevinKrumwiede, जैसा कि मैं देख रहा हूं कि यह एक वैचारिक वास्तविकता नहीं है। अलग-अलग लोग एक ही चीज़ के बारे में अलग-अलग तरीकों से सोचते हैं और लोग इसे कैसे बदल सकते हैं, इसके बारे में सोचते हैं। आप भौतिक और तार्किक कार्डों को अलग-अलग संस्थाओं के रूप में सोच सकते हैं। या आप किसी कार्ड की सामान्य धारणा के अपवाद के रूप में विभाजित कार्ड के बारे में सोच सकते हैं। न तो आंतरिक रूप से गलत है, लेकिन खुद को सरल मॉडलिंग के लिए उधार देता है।
विंस्टन एवर्ट

8

कुंद होने के लिए, मुझे लगता है कि प्रस्तावित समाधान बहुत अधिक प्रतिबंधात्मक है और भौतिक वास्तविकता से विमुख और तिरस्कृत है, थोड़ा लाभ के साथ मॉडल है।

मैं दो विकल्पों में से एक का सुझाव दूंगा:

विकल्प 1. इसे एकल कार्ड के रूप में समझें , जिसे आधा ए // आधा बी के रूप में पहचाना जाता है , जैसे एमटीजी साइट पहनें // आंसू । लेकिन, अपनी Cardइकाई को प्रत्येक विशेषता का एन शामिल करने की अनुमति दें : खेलने योग्य-नाम, मान लागत, प्रकार, दुर्लभता, पाठ, प्रभाव आदि।

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

विकल्प 2. विकल्प 1 से पूरी तरह से अलग नहीं है, इसे भौतिक वास्तविकता के बाद मॉडल करें। आपके पास एक Cardइकाई है जो एक भौतिक कार्ड का प्रतिनिधित्व करती है । और, यह उद्देश्य है कि एन Playable चीजों को धारण किया जाए । उन Playableप्रत्येक का एक अलग नाम हो सकता है, मन लागत, प्रभावों की सूची, क्षमताओं की सूची, आदि .. और आपके "भौतिक" का Cardअपना पहचानकर्ता (या नाम) हो सकता है जो प्रत्येक Playableके नाम का एक यौगिक है , बहुत पसंद है MTG डेटाबेस प्रतीत होता है।

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

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

मुझे लगता है कि इन विकल्पों में से कोई भी भौतिक वास्तविकता के बहुत करीब है। और, मुझे लगता है कि जो भी आपके कोड को देखता है, उसके लिए फायदेमंद होगा। (6 महीने में अपने आप की तरह।)


5

इन वस्तुओं का उद्देश्य वास्तव में कार्ड के गुणों को धारण करना है। वे वास्तव में खुद से कुछ नहीं करते हैं।

यह वाक्य एक संकेत है कि आपके डिजाइन में कुछ गड़बड़ है: OOP में, प्रत्येक वर्ग की ठीक एक भूमिका होनी चाहिए, और व्यवहार की कमी से एक संभावित डेटा क्लास का पता चलता है , जो कोड में एक बुरी गंध है।

आखिरकार, वे कार्ड हैं जो खुद का प्रतिनिधित्व करते हैं!

IMHO, यह थोड़ा अजीब लगता है, और थोड़ा अजीब भी। "कार्ड" प्रकार की एक वस्तु को एक कार्ड का प्रतिनिधित्व करना चाहिए। अवधि।

मुझे जादू के बारे में कुछ भी नहीं पता है : सभा , लेकिन मुझे लगता है कि आप अपने कार्ड का उपयोग उसी तरह करना चाहते हैं, जो कुछ भी उनकी वास्तविक संरचना है: आप एक स्ट्रिंग प्रतिनिधित्व प्रदर्शित करना चाहते हैं, आप एक हमले के मूल्य की गणना करना चाहते हैं, आदि।

आपके द्वारा वर्णित समस्या के लिए, मैं एक कंपोजिट डिज़ाइन पैटर्न की सिफारिश करूंगा , इस तथ्य के बावजूद कि यह डीपी आमतौर पर एक अधिक सामान्य समस्या को हल करने के लिए प्रस्तुत किया गया है:

  1. एक Cardइंटरफ़ेस बनाएँ , जैसा कि आपने पहले ही किया था।
  2. एक बनाएं ConcreteCard, जो लागू Cardकरता है और एक साधारण फेस कार्ड को परिभाषित करता है। इस वर्ग में एक सामान्य कार्ड के व्यवहार को रखने में संकोच न करें ।
  3. एक बनाएं CompositeCard, जो लागू करता है Cardऔर इसमें दो अतिरिक्त (और एक प्रायोरिटी निजी) हैं Card। चलो उन्हें बुलाओ leftCardऔर rightCard

दृष्टिकोण की भव्यता यह है कि CompositeCardइसमें दो कार्ड शामिल हैं, जो स्वयं कंक्रीटकार्ड या कम्पोजिटकार्ड हो सकते हैं। आपके गेम में, leftCardऔर rightCardसंभवतः व्यवस्थित रूप से होगा ConcreteCard, लेकिन डिज़ाइन पैटर्न आपको मुफ्त में उच्च स्तर की रचनाएँ डिज़ाइन करने की अनुमति देता है यदि आप चाहें। आपके कार्ड के हेरफेर में आपके कार्ड के वास्तविक प्रकार को ध्यान में नहीं रखा जाएगा, और इसलिए आपको उप-वर्ग के लिए कास्टिंग जैसी चीजों की आवश्यकता नहीं है।

CompositeCardCardनिश्चित रूप से निर्दिष्ट विधियों को लागू करना चाहिए , और यह इस तथ्य को ध्यान में रखते हुए करेंगे कि ऐसा कार्ड 2 कार्ड से बना है (इसके अलावा, यदि आप चाहें, तो CompositeCardकार्ड के लिए कुछ विशिष्ट है। उदाहरण के लिए, आप चाहते हो सकते हैं। निम्नलिखित कार्यान्वयन:

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, और विशिष्ट व्यवहार बहुरूपता के लिए छिपा हुआ है।

अगर आपको यकीन है कि एक CompositeCardवसीयत में हमेशा दो सामान्य Cardएस होते हैं , तो आप विचार रख सकते हैं, और बस ConcreateCardएक प्रकार के रूप में उपयोग करते हैं leftCardऔर rightCard


आप समग्र पैटर्न के बारे में बात कर रहे हैं , लेकिन वास्तव में जब से आप दो संदर्भों को पकड़ रहे हैं Card, CompositeCardआप डेकोरेटर पैटर्न को लागू कर रहे हैं । मैं इस समाधान का उपयोग करने के लिए ओपी को भी सलाह देता हूं, डेकोरेटर जाने का रास्ता है!
स्पॉट किया गया

मैं नहीं देखता कि दो कार्ड होने के कारण मेरी कक्षा को एक सज्जाकार कैसे बनाया जाता है। अपने स्वयं के लिंक के अनुसार, एक डेकोरेटर एकल ऑब्जेक्ट में सुविधाओं को जोड़ता है, और स्वयं इस ऑब्जेक्ट की तुलना में उसी वर्ग / इंटरफ़ेस का एक उदाहरण है। जबकि, आपके अन्य लिंक के अनुसार, एक सम्मिश्र एक ही वर्ग / इंटरफ़ेस की कई वस्तुओं के मालिक होने की अनुमति देता है। लेकिन अंततः शब्द मायने नहीं रखते हैं, और केवल विचार ही महान है।
मोगेनीमैन

@ स्‍पष्‍ट यह निश्चित रूप से डेकोरेटर पैटर्न नहीं है क्‍योंकि जावा में इस पद का उपयोग किया जाता है। डेकोरेटर पैटर्न एक व्यक्तिगत वस्तु पर तरीकों को ओवरराइड करके लागू किया जाता है, जिससे एक अनाम वर्ग बनता है जो उस वस्तु के लिए अद्वितीय होता है।
केविन क्रुमविडेड

@KevinKrumwiede जब तक CompositeCardअतिरिक्त तरीकों को उजागर नहीं करता है, CompositeCardकेवल एक डेकोरेटर है।
स्पॉट किया गया

"... डिजाइन पैटर्न आपको उच्च स्तरीय रचनाओं को मुफ्त में डिजाइन करने की अनुमति देता है" - नहीं, यह मुफ्त में नहीं आता है , बस विपरीत - यह एक समाधान होने की कीमत के लिए आता है जो आवश्यकताओं के लिए आवश्यकता से अधिक जटिल है।
डॉक ब्राउन

3

हो सकता है कि सब कुछ एक कार्ड है जब यह डेक या कब्रिस्तान में होता है, और जब आप इसे खेलते हैं, तो आप एक या एक से अधिक कार्ड ऑब्जेक्ट्स से एक प्राणी, भूमि, आकर्षण, इत्यादि का निर्माण करते हैं, जो सभी Playable को लागू या विस्तारित करते हैं। फिर, एक समग्र एकल प्लेएबल बन जाता है जिसका निर्माता दो आंशिक कार्ड लेता है, और एक किकर के साथ एक कार्ड एक प्लेएबल बन जाता है जिसका निर्माता मैना तर्क लेता है। प्रकार यह दर्शाता है कि आप इसके साथ क्या कर सकते हैं (ड्रा, ब्लॉक, डिस्पेल, टैप) और यह क्या प्रभाव डाल सकता है। या एक प्लेबल सिर्फ एक कार्ड है जिसे ध्यान से उल्टा करना पड़ता है (किसी भी बोनस और काउंटरों को खोने, विभाजित होने पर), खेल से बाहर ले जाने पर, अगर कार्ड को लागू करने के लिए उसी इंटरफ़ेस का उपयोग करना और यह भविष्यवाणी करना वास्तव में उपयोगी है।

शायद कार्ड और प्लेबल का प्रभाव है।


दुर्भाग्य से, मैं ये कार्ड नहीं खेलता। वे वास्तव में सिर्फ डेटा ऑब्जेक्ट हैं जिन्हें क्वेर किया जा सकता है। यदि आप एक डेक डेटा संरचना चाहते हैं, तो आप एक सूची <WholeCard> या कुछ और चाहते हैं। यदि आप ग्रीन इंस्टेंट कार्ड की खोज करना चाहते हैं, तो आप एक सूची <कार्ड> चाहते हैं।
कोडब्रेकर

आह ठीक है। आपकी समस्या के लिए बहुत प्रासंगिक नहीं है, तब। क्या मुझे हटा देना चाहिए?
डेविसलर

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जाने योग्य होने लगे हैं। आइए 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);
}

(यह अब के लिए इंटरफ़ेस का पहला संस्करण है। हम सुधार कर सकते हैं, जिस पर बाद में चर्चा की जाएगी।)

हमने अब सभी हिस्सों को हटा दिया है। अब हमें उन्हें एक साथ रखने की जरूरत है:

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इंटरफ़ेस में कर सकते हैं । उदाहरण के लिए, एक समय आ सकता है जब Cards में तीन या चार या पांच चेहरे हो सकते हैं। लागू करने के लिए नए तरीकों को जोड़ने के बजाय, हम दो मापदंडों के बजाय दूसरी विधि को ले सकते हैं और सरणी कर सकते हैं। यह समझ में आता है कि यदि बहु-सामना वाले कार्डों का अलग-अलग व्यवहार किया जाता है, लेकिन एक से ऊपर के चेहरों की संख्या समान रूप से व्यवहार की जाती है।

हम CardVisitorइंटरफ़ेस के बजाय एक अमूर्त वर्ग में भी बदल सकते हैं , और सभी तरीकों के लिए खाली कार्यान्वयन है। यह हमें केवल उन व्यवहारों को लागू करने की अनुमति देता है, जिनमें हम रुचि रखते हैं (शायद हम केवल एकल-सामना वाले Cardएस में रुचि रखते हैं )। हम उन तरीकों को लागू करने या संकलन करने में विफल रहने के लिए हर मौजूदा वर्ग को मजबूर किए बिना नए तरीके भी जोड़ सकते हैं।


1
मुझे लगता है कि इसे दूसरी तरह के दो सामना किए गए कार्ड (आगे और पीछे के बजाय साइड से) में आसानी से विस्तारित किया जा सकता है। ++
रबरडैक

आगे की खोज के लिए, एक उपवर्ग के लिए विशिष्ट तरीकों का शोषण करने के लिए एक विज़िटर के उपयोग को कभी-कभी मल्टीपल डिस्पैच कहा जाता है। डबल डिस्पैच समस्या का एक दिलचस्प समाधान हो सकता है।
मोगेनीमैन

1
मैं नीचे मतदान कर रहा हूं क्योंकि मुझे लगता है कि आगंतुक पैटर्न कोड में अनावश्यक जटिलता और युग्मन जोड़ता है। चूंकि एक विकल्प उपलब्ध है (mgoeminne का उत्तर देखें), मैं इसका उपयोग नहीं करूंगा।
स्पॉट किया गया

आगंतुक @Spotted है एक जटिल पैटर्न, और मैं भी समग्र पैटर्न जब जवाब लिख माना जाता है। आगंतुक के साथ जाने का कारण यह है कि ओपी समान चीजों के बजाय अलग-अलग चीजों के समान व्यवहार करना चाहता है। यदि कार्डों में अधिक व्यवहार था, और गेमप्ले के लिए उपयोग किया जा रहा था, तो समग्र पैटर्न एकीकृत डेटा का उत्पादन करने के लिए डेटा के संयोजन की अनुमति देता है। वे डेटा के सिर्फ बैग हैं, हालांकि, संभवतः एक कार्ड डिस्प्ले रेंडर करते थे, जिसमें अलग-अलग जानकारी प्राप्त करना एक साधारण समग्र एग्रीगेटर की तुलना में अधिक उपयोगी लगता था।
कोबरा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.