मेरे पास एक प्रोजेक्ट है जो ऐप में मौजूद कुछ राज्यों और मोड के आधार पर कुछ डेटा प्रिंट कर सकता है।

enum Mode {
   mode1 = 0,
   mode2
};

enum State {
   state1 = 0,
   state2
};

डेटा को कई तरीकों से प्रिंट किया जा सकता है, यहां कुछ उदाहरण दिए गए हैं:

1. name1 value1 name2 value2 name3 value3

2. value1 value2 value3

3. name1 : value1.  
   name2 : value2   
   name3 : value3  

मैंने ओस्ट्रीम ऑपरेटर अधिभार के साथ कक्षा बनाने की कोशिश की:

class Formater {
public:
   Formater(.....) { ... } // pass name, value, mode, state here.

   virtual void print_State1_Mode1(ostream& os) { }
   virtual void print_State1_Mode2(ostream& os) { }
   virtual void print_State2_Mode1(ostream& os) { }
   virtual void print_State2_Mode2(ostream& os) { }

    friend std::ostream& operator << (std::ostream& os, const Formater& f) {
        if (state1 & mode1) {
            print_State1_Mode1(os);
        }
        else if(state1 & mode2) {
            print_State1_Mode2(os);
        }
        else if(state2 & mode1) {
            print_State2_Mode1(os);
        }
        else {
            print_State2_Mode2(os);
        }

        return os;
    } 
};

इसका उपयोग कुछ कमांड के लिए किया जाएगा और राज्य और मोड के आधार पर प्रत्येक कमांड में टेक्स्ट प्रिंट करने के लिए अलग-अलग प्रारूप हो सकते हैं।

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

तो मैं कई और फॉर्मेटर ऑब्जेक्ट्स (फॉर्मेटर 1, फॉर्मेटर 2 ....) के साथ समाप्त कर सकता हूं।

मैं इस दृष्टिकोण से 100% संतुष्ट नहीं हूं। क्या किसी के पास बेहतर डिज़ाइन या तरीके हैं जिनसे मैं अपने वर्तमान डिज़ाइन को बेहतर बना सकता हूँ?

0
Adrian 14 अप्रैल 2018, 13:02

2 जवाब

सबसे बढ़िया उत्तर

मैं नहीं देखता कि यह सरल डिज़ाइन पर्याप्त क्यों नहीं है।

class Formatter {
  ...
  virtual std::ostream& insert(std::ostream&) const = 0;
  friend std::ostream& operator<<(std::ostream& os, const Formatter& fmt) {
    return fmt.insert(os); 
  }
};

class Formatter_State1_Mode1: public Formatter {
  ...
  std::ostream& insert(std::ostream&) const override;
};

class Formatter_State1_Mode2: public Formatter {
  ...
  std::ostream& insert(std::ostream&) const override;
};

Formatter* makeFormatter(Mode, State, ...);

यह बदसूरत अगर-सीढ़ी से छुटकारा दिलाता है और बेहतर प्रदर्शन देता है।

1
Lingxi 14 अप्रैल 2018, 13:51

मैं आपको यहां Bridge पैटर्न का उपयोग करने का सुझाव दूंगा। उसके लिए आपकी कार्यक्षमता को ध्यान से दो भागों में विभाजित किया जाना चाहिए। तो आपका स्टेट एब्स्ट्रैक्शन या रिफाइंड एब्स्ट्रैक्शन होना चाहिए। और Formatter, Implementor होगा। फिर आपके पास ConcreteImplementors के रूप में अलग-अलग फॉर्मेटर्स हो सकते हैं। आप कुछ कॉन्फिग प्रॉपर्टी के आधार पर फॉर्मेटर प्राप्त करने के लिए AbstractFactory फॉर्मेटर फैक्ट्री का उपयोग कर सकते हैं। इस तर्क को अपने द्वारा परिभाषित किया जाना चाहिए।

यहां Bridge Pattern की परिभाषा Gang of Four द्वारा दी गई है: एक अमूर्त को इसके कार्यान्वयन से अलग करें ताकि दोनों स्वतंत्र रूप से भिन्न हो सकें।

1
Ravindra Ranwala 14 अप्रैल 2018, 13:24