2012-11-13 37 views
8

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

class AbstractHandler 
{ 
public: 
    virtual void handleMessage(const MessageType1& msg) =0; 
    virtual void handleMessage(const MessageType2& msg) =0; 
    virtual void handleMessage(const MessageType3& msg) =0; 
    virtual void handleMessage(const MessageType4& msg) =0; 
}; 

और फिर व्युत्पन्न बनाने ठोस वर्ग कि हैंडलर कार्यों को लागू:

class ConcreteHandler : public AbstractHandler 
{ 
public: 
    virtual void handleMessage(const MessageType1& msg); 
    virtual void handleMessage(const MessageType2& msg); 
    virtual void handleMessage(const MessageType3& msg); 
    virtual void handleMessage(const MessageType4& msg); 
}; 

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

वैकल्पिक रूप से मैं mpl अनुक्रम में सभी समर्थित संदेश प्रकारों को पकड़ सकता हूं, और सार आधार वर्ग उत्पन्न करने के लिए mpl::inherit_linearly का उपयोग कर सकता हूं।

(नोट: मैं पहले से ही कोड में कहीं और संदेश प्रकारों के mpl::vector का उपयोग करें।)

उदाहरण के लिए:

typedef mpl::vector< MessageType1, MessageType2, 
        MessageType3, MessageType4 > message_types; 

template< class Message > 
class Wrapper 
{ 
public: 
    virtual void handleMessage(const Message& msg) = 0; 
protected: 
    ~Wrapper(){} 
}; 

class AbstractHandler 
    : public mpl::inherit_linearly< message_types 
            , mpl::inherit< mpl_1, Wrapper<mpl::_2> > 
            >::type 
{ 
public: 
    virtual ~AbstractHandler() {} 
}; 

कंक्रीट संचालकों तो AbstractHandler से निकाले जाते हैं। इसका अर्थ यह है कि जब भी सिस्टम में नए संदेश प्रकार जोड़े जाते हैं तो यह mpl::vector<types...> message_types अनुक्रम को बदलने का मामला है, जो व्युत्पन्न कक्षाओं में नए handleMessage फ़ंक्शंस जोड़ना जोड़ता है।

मेरी राय में इस लंबी अवधि के रखरखाव कम कर देता है, के बाद से AbstractHandler स्वचालित रूप से प्रदर्शन के संदर्भ में mpl::vector message_types

में सभी संदेशों के लिए शुद्ध आभासी कार्यों होगा कि इस दृष्टिकोण का उपयोग करने के लिए किसी भी कमियां हैं?

अमूर्त बेस कक्षाएं उत्पन्न करने के लिए mpl::inherit_linearly का उपयोग करने के प्रभाव क्या हैं?

उत्तर

3

मैंने पहले समान कोड किया है (और मैं इसे फिर से कर रहा हूं)।

विरासत से प्रेरित लागतों के अलावा कोई कीमत नहीं है। मुख्य रूप से क्योंकि अंतिम प्रकार संकलन समय पर निर्धारित होता है, रनटाइम नहीं।

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

अन्यथा, यह अच्छा है।

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

+0

इस पर मेरे विचारों की पुष्टि करने के लिए धन्यवाद। अब मेरे पास एक कामकाजी समाधान है जो एक एपीआई का हिस्सा है जो क्लाइंट सेवाओं को संदेश संसाधित करते समय उपयोग करता है। अब तक एपीआई जैसे सभी उपयोगकर्ता ... एमपीएल निश्चित रूप से मजबूत कोड का उत्पादन करने में मदद करता है ... – mark

+0

उपयोगकर्ता की तरफ इसके कुछ दोष हैं हालांकि: यह कम स्पष्ट है कि कार्यों को परिभाषित किया जाना चाहिए। एक अच्छा (हालिया) कंपाइलर एक स्पष्ट संदेश देगा, इसलिए मुझे लगता है कि यह ठीक है। यह बेहतर होगा यदि उपयोगकर्ता को कार्यों को स्पष्ट रूप से ओवरराइड करने के लिए मजबूर करने का कोई तरीका था (यह सुनिश्चित करने के लिए कि वे गलतियां नहीं करते हैं)। – Klaim