समान हस्ताक्षर वाले दो इंटरफेस


13

मैं एक कार्ड गेम तैयार करने का प्रयास कर रहा हूँ जहाँ कार्ड में दो महत्वपूर्ण सुविधाएँ हैं:

पहला एक प्रभाव है। ये गेम स्टेट में होने वाले बदलाव हैं जब आप कार्ड खेलते हैं। प्रभाव के लिए इंटरफ़ेस इस प्रकार है:

boolean isPlayable(Player p, GameState gs);
void play(Player p, GameState gs);

और आप कार्ड को खेलने योग्य मान सकते हैं यदि और केवल तभी यदि आप इसकी लागत को पूरा कर सकते हैं और इसके सभी प्रभाव खेलने योग्य हैं। इस तरह:

// in Card class
boolean isPlayable(Player p, GameState gs) {
    if(p.resource < this.cost) return false;
    for(Effect e : this.effects) {
        if(!e.isPlayable(p,gs)) return false;
    }
    return true;
}

ठीक है, अब तक, बहुत सरल है।

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

boolean isActivatable(Player p, GameState gs);
void activate(Player p, GameState gs);

और मुझे एहसास है कि इसे "खेलने" के बजाय "सक्रिय" कहने के अपवाद के साथ, Abilityऔर Effectसटीक एक ही हस्ताक्षर है।


क्या एक समान हस्ताक्षर के साथ कई इंटरफेस होना बुरी बात है? क्या मुझे बस एक का उपयोग करना चाहिए, और एक ही इंटरफ़ेस के दो सेट हैं? यथा:

Set<Effect> effects;
Set<Effect> abilities;

यदि हां, तो क्या पुनर्रचना चरणों मैं नीचे सड़क अगर वे असमान (और अधिक सुविधाओं जारी कर रहे हैं के रूप में) हो जाते हैं, विशेष रूप से अगर वे अलग-अलग (वे दोनों लाभ कुछ अन्य नहीं करना चाहिए अर्थात्, के रूप में केवल एक ही प्राप्त कर रहा करने के लिए विरोध लेना चाहिए और दूसरा एक पूर्ण उपसमूह है)? मुझे विशेष रूप से चिंता है कि कुछ परिवर्तन होते ही उनका संयोजन गैर-टिकाऊ होगा।

बारीक अक्षर:

मुझे लगता है कि यह सवाल खेल के विकास से पैदा हुआ है, लेकिन मुझे लगता है कि यह उस तरह की समस्या है जो आसानी से गैर-खेल के विकास में रेंग सकती है, खासकर जब एक आवेदन में कई ग्राहकों के व्यापार मॉडल को समायोजित करने का प्रयास किया जाता है जैसा कि बस के साथ होता है हर परियोजना जो मैंने कभी एक से अधिक व्यावसायिक प्रभाव के साथ की है ... इसके अलावा, उपयोग किए जाने वाले स्निपेट जावा स्निपेट हैं, लेकिन यह आसानी से ऑब्जेक्ट ओरिएंटेड भाषाओं की भीड़ पर लागू हो सकता है।


बस का पालन करें KISS और YAGNI और आप ठीक होना चाहिए।
बर्नार्ड

2
केवल यही कारण है कि यह सवाल इसलिए भी प्रकट होता है क्योंकि अविश्वसनीय रूप से विस्तृत और अप्रतिबंधित प्लेयर और गेमस्टेट मापदंडों के कारण आपके कार्यों की पहुंच बहुत अधिक है।
लार्स विकलंड

जवाबों:


18

सिर्फ इसलिए कि दो इंटरफेस में एक ही अनुबंध है, इसका मतलब यह नहीं है कि वे एक ही इंटरफ़ेस हैं।

लिस्कोव प्रतिस्थापन सिद्धांत :

मान लीजिए कि क्ष (x) प्रकार की वस्तुओं के बारे में सिद्ध हो सकता है, जैसे कि टाइप T का। तब q (y) को S के उन वस्तुओं के लिए सिद्ध होना चाहिए जहां S, T का उप-प्रकार है।

या, दूसरे शब्दों में: जो कुछ भी एक इंटरफ़ेस या सुपरटेप का सच है, वह उसके सभी उपप्रकारों के लिए सही होना चाहिए।

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


2

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

एक और बात जो आपने कही है वह यह है कि यदि उन व्यवहारों में से एक बदल जाए। तब क्या होता है जब आपके पास सिर्फ एक इंटरफ़ेस होता है?


1

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

उन्होंने कहा, अगर वे बेहद समान हैं, तो उन्हें एक सामान्य पूर्वज से प्राप्त करने का कोई मतलब हो सकता है। सावधानी से विचार करें: यदि आपको लगता है कि "प्रभाव" और "क्षमताओं" हमेशा जाएगा कारण क्या है जरूरी एक ही इंटरफ़ेस है? यदि आप effectइंटरफ़ेस में एक तत्व जोड़ते हैं , तो क्या आप abilityइंटरफ़ेस में जोड़े गए उसी तत्व की आवश्यकता की उम्मीद करेंगे ?

यदि ऐसा है, तो आप ऐसे तत्वों को एक सामान्य featureइंटरफ़ेस में रख सकते हैं जिससे वे दोनों व्युत्पन्न हैं। यदि नहीं, तो आपको उन्हें एकजुट करने की कोशिश नहीं करनी चाहिए - आप अपना समय आधार और व्युत्पन्न इंटरफेस के बीच सामान ले जाने में बर्बाद करेंगे। हालाँकि, जब से आप वास्तव में किसी भी चीज़ के लिए सामान्य आधार इंटरफ़ेस का उपयोग करने का इरादा नहीं रखते हैं, लेकिन "अपने आप को दोहराएं नहीं", तो यह उतना अंतर नहीं कर सकता है। और, यदि आप उस इरादे से चिपके रहते हैं, तो मेरा अनुमान है कि यदि आप शुरुआत में गलत चुनाव करते हैं, तो बाद में इसे ठीक करने के लिए फिर से तैयार करना अपेक्षाकृत सरल हो सकता है।


0

आप जो देख रहे हैं, वह मूल रूप से टाइप सिस्टम की सीमित अभिव्यक्ति की एक कलाकृति है।

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

अब, विभिन्न प्रकार की प्रणालियों में अभिव्यंजकता की भिन्नता होती है, लेकिन हमेशा कुछ ऐसा होगा जिसे व्यक्त नहीं किया जा सकता है।

उदाहरण के लिए: दो इंटरफेस जिनके अलग-अलग त्रुटि व्यवहार हैं, C # में एक ही हस्ताक्षर हो सकता है, लेकिन जावा में नहीं (क्योंकि जावा अपवाद हस्ताक्षर का हिस्सा हैं)। दो इंटरफेस जिनके व्यवहार केवल उनके साइड-इफेक्ट में भिन्न होते हैं, जावा में एक ही हस्ताक्षर हो सकते हैं, लेकिन हास्केल में अलग हस्ताक्षर होंगे।

इसलिए, यह हमेशा संभव है कि आप विभिन्न व्यवहारों के लिए एक ही हस्ताक्षर के साथ समाप्त हो जाएंगे। यदि आपको लगता है कि यह महत्वपूर्ण है कि उन दो व्यवहारों के बीच सिर्फ एक मामूली स्तर पर अंतर करने में सक्षम होने के लिए, तो आपको अधिक (या अलग) अभिव्यंजक प्रकार प्रणाली पर स्विच करने की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.