कौन सा बेहतर है: चयन स्ट्रिंग पैरामीटर के साथ गेटर्स या 1 विधि का एक गुच्छा?


15

हमारे ज्ञान डोमेन में अपने नंगे पैरों के साथ दबाव-रिकॉर्डिंग प्लेट पर चलने वाले लोग शामिल हैं। हम छवि की पहचान करते हैं, जिसके परिणामस्वरूप 'फुट' वर्ग की वस्तुएं होती हैं, यदि सेंसर डेटा में एक मानव पैर को मान्यता दी जाती है।

कई गणनाएं हैं जिन्हें पैर के डेटा पर किया जाना चाहिए।

अब, कौन सा API बेहतर होगा:

class Foot : public RecognizedObject  { 
  MaxPressureFrame getMaxPressureFrame();
  FootAxis getFootAxis();
  AnatomicalZones getAnatomicalZones();

  // + similar getters for other calculations

  // ...
}

या:

class Foot : public RecognizedObject {
  virtual CalculationBase getCalculation(QString aName);

  // ...
}

अब, वहाँ बहुत सारे हैं Pro और con मैं के साथ आ सकते हैं, लेकिन मैं वास्तव में तय नहीं कर सकते हैं जो सबसे महत्वपूर्ण हैं। ध्यान दें, यह एंड-यूज़र एप्लिकेशन है, न कि एक सॉफ़्टवेयर लाइब्रेरी जो हम बेचते हैं।

कोई सुझाव?

पहले दृष्टिकोण के लिए कुछ समर्थक हो सकते हैं:

  • KISS - सब कुछ बहुत ठोस है। एपीआई, लेकिन कार्यान्वयन भी।
  • दृढ़ता से टाइप किए गए रिटर्न मान।
  • इस वर्ग से विरासत में लेना मूर्खतापूर्ण है। कुछ भी ओवरराइड नहीं किया जा सकता है, केवल जोड़ा गया है।
  • एपीआई बहुत बंद है, कुछ भी अंदर नहीं जाता है, कुछ भी ओवरराइड नहीं किया जा सकता है, इसलिए कम गलत हो सकता है।

कुछ चोरों का:

  • गेटर्स की संख्या बढ़ेगी, क्योंकि हमारे द्वारा गणना की गई हर नई गणना सूची में जुड़ जाती है
  • एपीआई में बदलाव की संभावना अधिक होती है, और यदि ब्रेकिंग परिवर्तन पेश किए जाते हैं, तो हमें एक नया एपीआई संस्करण, एक Foot2 की आवश्यकता है।
  • अन्य परियोजनाओं में वर्ग के पुन: उपयोग के मामले में, हमें हर गणना की आवश्यकता नहीं हो सकती है

दूसरे दृष्टिकोण के लिए कुछ समर्थक:

  • अधिक लचीला
  • एपीआई को बदलने की संभावना कम है, (यह मानते हुए कि हमें अमूर्तता सही लगी, यदि नहीं, तो बदलने में अधिक लागत आएगी)

कुछ चोरों का:

  • शिथिल टाइप। हर आह्वान पर जातियां चाहिए।
  • स्ट्रिंग पैरामीटर - मेरे मन में इसके बारे में गलत भावनाएँ हैं (स्ट्रिंग मूल्यों पर शाखा ...)
  • कोई वर्तमान उपयोग मामला / आवश्यकता नहीं है जो अतिरिक्त लचीलेपन को अनिवार्य करता है, लेकिन भविष्य में हो सकता है।
  • एपीआई प्रतिबंध लगाता है: हर गणना को एक बेस क्लास से प्राप्त करना होगा। गणना प्राप्त करना इस 1 विधि के माध्यम से मजबूर हो जाएगा, और अतिरिक्त मापदंडों को पारित करना असंभव होगा, जब तक कि हम गुजरने वाले मापदंडों के एक भी अधिक गतिशील, सुपर-लचीले तरीके से वसीयत नहीं करते हैं जो जटिलता को और भी अधिक बढ़ाता है।

5
आप एक enumमान बना सकते हैं और उस पर स्विच कर सकते हैं । फिर भी, मुझे लगता है कि दूसरा विकल्प बुराई है, क्योंकि यह KISS से भटक।
वोरैक

यदि आप इसे ट्रिगर करने के लिए एक स्ट्रिंग पैरामीटर का उपयोग करते हैं, तो एक विशिष्ट गणना के सभी उपयोगों को खोजने के लिए कठिन है। मुश्किल से 100% आप उन सभी को मिला।
कोनराड मोरावस्की

दो दुनियाओं में से सबसे अच्छा ले लो और हमलावरों के झुंड के साथ एक बहाना लिखो getCalculation()
नालपुरी

1
Enums निश्चित रूप से तार से बेहतर हैं! मैंने यह नहीं सोचा था। वे एपीआई को प्रतिबंधित करते हैं और स्ट्रिंग पैरामीटर के दुरुपयोग को रोकते हैं (जैसे कि टोकन और अन्य बकवास की तरह) इसलिए मुझे लगता है कि तुलना 1 और विकल्प 2 के बीच स्ट्रिंग के बजाय एनम के साथ है।
बग्गी

जवाबों:


6

मुझे लगता है कि पहले दृष्टिकोण में भुगतान करना होगा। मैजिक स्ट्रिंग्स निम्न समस्याएँ पैदा कर सकती हैं: टाइपिंग त्रुटियां, दुरुपयोग, गैर-तुच्छ वापसी प्रकार की सुरक्षा, कोड पूरा होने की कमी, अस्पष्ट कोड (क्या इस संस्करण में वह विशेषता है? मुझे लगता है कि हम रनटाइम पर पता लगाएंगे)। एनम का उपयोग करने से उन मुद्दों में से कुछ हल हो जाएंगे, लेकिन आइए आपके द्वारा उठाए गए दृष्टिकोण को देखें:

  • गेटर्स की संख्या बढ़ेगी, क्योंकि हमारे द्वारा गणना की गई हर नई गणना सूची में जुड़ जाती है

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

  • एपीआई में बदलाव की संभावना अधिक होती है, और यदि ब्रेकिंग परिवर्तन पेश किए जाते हैं, तो हमें एक नया एपीआई संस्करण, एक Foot2 की आवश्यकता है।

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

  • अन्य परियोजनाओं में वर्ग के पुन: उपयोग के मामले में, हमें हर गणना की आवश्यकता नहीं हो सकती है

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


मुझे इंटरफेस के साथ आंशिक एपीआई विचार पसंद है, यह भविष्य में प्रूफ लगता है। मैं उस एक के साथ जाऊंगा। धन्यवाद। यदि यह बहुत अधिक अव्यवस्थित हो जाता है (पैर बहुत अधिक इंटरफेस को लागू करता है), तो कई छोटे एडेप्टर वर्गों का उपयोग करना और भी अधिक लचीला होगा: यदि विभिन्न एपी के साथ पैर की कई विविधताएं मौजूद हैं (जैसे पैर, ह्यूमनफुट, डॉगफुट, मानवफुटवर्जन 2) एक छोटा एडेप्टर हो सकता है प्रत्येक के लिए एक GUI विजेट को उन सभी के साथ काम करने की अनुमति देने के लिए ...
Bgie

कमांड सिलेक्टर का उपयोग करने का एक फायदा यह है कि एक कार्यान्वयन हो सकता है जो एक कमांड प्राप्त करता है जो इंटरफ़ेस के साथ प्रदान की गई स्थिर सहायक विधि को नहीं समझता है। यदि कमांड ऐसी चीज़ का प्रतिनिधित्व करता है, जो सामान्य-उद्देश्य दृष्टिकोण का उपयोग करके लगभग सभी कार्यान्वयनों के साथ किया जा सकता है, लेकिन जो कुछ कार्यान्वयन बेहतर तरीकों से कर सकते हैं [उदाहरण पर विचार करें IEnumerable<T>.Count], ऐसा दृष्टिकोण कोड को नए के प्रदर्शन लाभों का आनंद लेने की अनुमति दे सकता है कार्यान्वयन का उपयोग करते समय इंटरफ़ेस सुविधाएँ जो उनका समर्थन करती हैं, लेकिन पुराने कार्यान्वयन के साथ संगत रहती हैं।
Supercat

12

मैं विकल्प 3 की सिफारिश करूंगा: यह स्पष्ट कर दें कि गणना किसी के अमूर्तन का आंतरिक हिस्सा नहीं है Foot, लेकिन इसके साथ काम करते हैं। फिर आप Footअलग-अलग वर्गों में गणना और गणना कर सकते हैं, जैसे:

class Foot : public RecognizedObject {
public:
    // Rather low-level API to access all characteristics that might be needed by a calculation
};

class MaxPressureFrame {
public:
    MaxPressureFrame(const Foot& aFoot); // Performs the calculation based on the information in aFoot
    //API for accessing the results of the calculation
};

// Similar classes for other calculations

इस तरह, आपके पास अभी भी आपकी गणना का मजबूत प्रकार है, और आप मौजूदा कोड को प्रभावित किए बिना नए जोड़ सकते हैं (जब तक कि आपके द्वारा उजागर की गई राशि की जानकारी में कोई गंभीर त्रुटि न हो Foot)।


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

4
यह उचित हो सकता है। यह ओवरकिल हो सकता है। गणना कितनी जटिल है, इस पर निर्भर करता है। आप एक MaxPressureFrameStrategy और एक MaxPressureFrameStrategyFactory जोड़ने जा रहे हैं? और यह पैर को एनीमिक ऑब्जेक्ट में बदल देता है।
user949300

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

@Bgie: गणना के बीच इस तरह निर्भरता के साथ, मैं @ user116462 कि पहला विकल्प best.` है के साथ सहमत
बार्ट वैन इन्जेन Schenau
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.