रणनीति के साथ टेम्पलेट विधि का संयोजन


14

मेरे सॉफ्टवेयर इंजीनियरिंग वर्ग में एक असाइनमेंट एक एप्लीकेशन डिजाइन करना है जो विभिन्न रूपों को एक विशेष गेम खेल सकता है। विचाराधीन खेल मंचला है, इनमें से कुछ खेलों को वारी या कलाह कहा जाता है। ये खेल कुछ पहलुओं में भिन्न हैं, लेकिन मेरे प्रश्न के लिए यह जानना महत्वपूर्ण है कि खेल निम्नलिखित में भिन्न हो सकते हैं:

  • जिस तरह से एक चाल के परिणाम को संभाला जाता है
  • जिस तरह से खेल का अंत निर्धारित किया जाता है
  • जिस तरह से विजेता निर्धारित किया जाता है

पहली बात यह है कि मेरे दिमाग में यह डिजाइन करने के लिए आया था कि रणनीति पैटर्न का उपयोग करें, मेरे पास एल्गोरिदम (गेम के वास्तविक नियम) में भिन्नता है। डिजाइन इस तरह दिख सकता है: यहाँ छवि विवरण दर्ज करें

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

मैं इसके बाद आया: यहाँ छवि विवरण दर्ज करें

प्रत्येक खेल (मनकाला, वारि, कलाह, ...) में प्रत्येक नियम के इंटरफ़ेस के प्रकार की विशेषता होगी, अर्थात WinnerDeterminerऔर यदि कोई मनकाला २.० संस्करण है जो मानकाला १.० के समान है, सिवाय इसके कि विजेता कैसे निर्धारित होता है, बस Mancala संस्करणों का उपयोग करें।

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

टेम्पलेट पद्धति पैटर्न के बारे में पढ़ने में मुझे तुरंत लगा कि इसे इस समस्या पर लागू किया जा सकता है। उपयोगकर्ता द्वारा किए जाने पर किए जाने वाले कार्य हमेशा एक जैसे होते हैं, और एक ही क्रम में, अर्थात्:

  • छेद में पत्थर जमा करना (यह सभी खेलों के लिए समान है, इसलिए इसे टेम्पलेट विधि में लागू किया जाएगा)
  • चाल का परिणाम निर्धारित करें
  • निर्धारित करें कि क्या खेल पिछले चाल के कारण समाप्त हो गया है
  • यदि खेल समाप्त हो गया है, तो निर्धारित करें कि कौन जीता है

ऊपर वर्णित मेरी रणनीति पैटर्न में वे तीन अंतिम चरण हैं। मुझे इन दोनों को मिलाने में बहुत परेशानी हो रही है। एक संभावित समाधान जो मैंने पाया वह है कि रणनीति पैटर्न को छोड़ना और निम्नलिखित कार्य करना चाहिए: यहाँ छवि विवरण दर्ज करें

मैं वास्तव में रणनीति पैटर्न और इसके बीच के अंतर को नहीं देखता हूं? लेकिन मैं निश्चित हूं कि मुझे एक टेम्पलेट पद्धति का उपयोग करने की आवश्यकता है (हालांकि मैं रणनीति पैटर्न का उपयोग करने के बारे में निश्चित था)।

मैं यह भी निर्धारित नहीं कर सकता कि TurnTemplateऑब्जेक्ट बनाने के लिए कौन जिम्मेदार होगा , जबकि रणनीति पैटर्न के साथ मुझे लगता है कि मेरे पास वस्तुओं के परिवार (तीन नियम) हैं जो मैं आसानी से एक अमूर्त कारखाना पैटर्न का उपयोग करके बना सकता हूं। मेरे पास तब ए MancalaRuleFactory, WariRuleFactoryआदि होगा, और वे नियमों के सही उदाहरण बनाएंगे और मुझे एक RuleSetवस्तु वापस देंगे ।

मान लीजिए कि मैं रणनीति + अमूर्त कारखाने पैटर्न का उपयोग करता हूं और मेरे पास एक RuleSetवस्तु है जिसमें तीन नियमों के लिए एल्गोरिदम हैं। एकमात्र तरीका मुझे लगता है कि मैं अभी भी टेम्पलेट विधि पैटर्न का उपयोग कर सकता हूं, इस RuleSetऑब्जेक्ट को मेरे पास करना है TurnTemplate। तब 'समस्या' जो कि सतहों की है कि मुझे अपने ठोस कार्यान्वयन की कभी आवश्यकता नहीं होगी TurnTemplate, ये वर्ग अप्रचलित हो जाएंगे। अपने संरक्षित तरीकों में TurnTemplateमैं बस फोन कर सकता था ruleSet.determineWinner()। परिणामस्वरूप, TurnTemplateवर्ग अब अमूर्त नहीं होगा, बल्कि उसे ठोस बनना होगा, क्या यह तब भी एक टेम्पलेट पद्धति है?

संक्षेप में, क्या मैं सही तरीके से सोच रहा हूं या क्या मैं कुछ आसान याद कर रहा हूं? यदि मैं सही रास्ते पर हूं, तो मैं रणनीति पैटर्न और टेम्पलेट पद्धति पैटर्न को कैसे संयोजित करूं?


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

" ... मनकला और वारी के खेल में जिस तरह से विजेता का निर्धारण किया जाता है वह बिल्कुल वैसा ही होता है और कोड को डुप्लिकेट किया जाएगा। " ऐसा क्यों है कि कोड डुप्लिकेट है? बस दोनों वर्गों को एक ही फ़ंक्शन को कॉल करने दें।
डी ड्रमर

जवाबों:


6

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

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

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

आपका तीसरा डिज़ाइन वह है जो मुझे सबसे अच्छा लगता है। मेरी एकमात्र चिंता यह है कि यह अमूर्तता के सही स्तर पर नहीं है। अभी, आप एक मोड़ पर मॉडलिंग करते दिखाई देते हैं। मैं खेल को डिजाइन करने पर विचार करने की सलाह दूंगा। गौर कीजिए कि आपके पास ऐसे खिलाड़ी हैं जो पत्थरों का इस्तेमाल करके किसी तरह के बोर्ड पर कदम रख रहे हैं। आपके खेल के लिए इन अभिनेताओं को उपस्थित होना आवश्यक है। वहां से, आपका एल्गोरिथ्म नहीं है , doTurn()लेकिन playGame()जो प्रारंभिक चाल से अंतिम चाल तक जाता है, जिसके बाद वह समाप्त हो जाता है। प्रत्येक खिलाड़ी के कदम के बाद, यह खेल की स्थिति को समायोजित करता है, यह निर्धारित करता है कि क्या खेल अंतिम स्थिति में है, और यदि यह है, तो विजेता निर्धारित करता है।

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


चूंकि आप एक छात्र हैं, इसलिए मैं एक समय से कुछ चीजें साझा करना चाहता हूं जब मैं एक सॉफ्टवेयर डिजाइन पाठ्यक्रम के लिए टीए था:

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

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

3

आपका भ्रम उचित है। बात यह है कि पैटर्न परस्पर अनन्य नहीं हैं।

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

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

@ThomasOwens आपकी विशेष समस्या के बारे में उत्कृष्ट सलाह देता है।


0

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


2
हालांकि आम तौर पर मैं आपसे सहमत हूं , यह वास्तव में एक जवाब नहीं है जो ओपी की समस्या को हल करता है। "ऐसा मत करो" एक जवाब है, लेकिन एक गरीब अगर यह एक व्यवहार्य विकल्प प्रदान नहीं करता है।
यानिस

@YannisRizos और जब तक मैं आपके साथ सहमत हूं , मुझे अभी भी लगता है कि उन्होंने ध्वनि सलाह दी थी (या अगर सलाह सही शब्द नहीं है तो अंतर्दृष्टि)। उस कारण से, +1। हालांकि, हाँ, यह तकनीकी रूप से बहुत उपयोगी उत्तर नहीं है।
bought777

-1

चलो पीतल के ढेर के लिए नीचे उतरो। किसी भी गेम इंटरफ़ेस, कोई डिज़ाइन पैटर्न, कोई अमूर्त वर्ग और कोई UML की कोई आवश्यकता नहीं है।

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

तो यहाँ जाने का समझदार तरीका यह है कि एक सामान्य कार्यात्मक अमूर्तता का उपयोग किया जाए, जैसे C # 's Actionया C ++' std::function, एक मनकाला, एक वारि और एक कलाह क्लास बनाएँ, और वहाँ से जाएँ।

std::unordered_map<std::string, std::function<void()>> games = {
    { "Kalah", [] { return Kalah(); } },
    { "Mancala", [] { return Mancala(); } },
    { "Wari", [] { return Wari(); } }
};
void play() {
    std::function<void()> f;
    f = games[GetChoiceFromUI()];
    f();
    if (PlayAgain()) return play();
}
int main() {
    play();
}

किया हुआ।

आप खेल नहीं कहते हैं। गेम्स आपको बुलाते हैं।


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

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

4
सॉफ्टडेव में एक चिंताजनक / कष्टप्रद प्रवृत्ति है जहां उपयोग किए गए डिज़ाइन पैटर्न को समस्या को हल करने की तुलना में अधिक महत्वपूर्ण माना जाता है। ओवर-इंजीनियरिंग जैसी कोई चीज होती है।
जेम्स

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

2
मेरा पूरा जीवन मैंने हमेशा सोचा है कि यह "पीतल कर" था ... वाह, "पीतल के ढेर" अधिक समझ में आता है। lol
97740 पर 7
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.