2011-12-14 22 views
10

हम वीसी 6 कंपाइलर के साथ सी ++ में लागू बहुत पुरानी विरासत प्रणाली के साथ काम करते हैं। अब हम कोड को दोबारा करने की प्रक्रिया में हैं। हमने वीसी 9 कंपाइलर पर भी स्विच किया।लीगेसी एपीआई/फ्रेमवर्क (सी ++ मैक्रोज़ बनाम सी ++ टेम्पलेट बनाम कोड जेनरेटर) के लिए बड़ी संख्या में जटिल रैपर को कैसे कार्यान्वित करें?

हम बाहरी मालिकाना ढांचे का उपयोग करते हैं, जो विरासत कोड भी है और इकाई परीक्षण योग्य नहीं है। ताकि हमारे कोड इकाई परीक्षण योग्य बनाने के लिए, हम फ्रेमवर्क वर्गों के लिए इंटरफेस और रैपर शुरू की (संकेत: देखने मार्टिन Fowler द्वारा "परंपरागत कोड के साथ काम करना"):

enter image description here

अब हम इंटरफेस पर निर्भर करते हैं। रैपर ढांचे के तरीकों को बुलाते हैं और हम खुशी से हमारे यूनिट परीक्षणों में मोजे का उपयोग कर सकते हैं।

और यहाँ हम अपने समस्या के लिए आते हैं ...

फ्रेमवर्क वर्गों कई तरीके लपेटा जाता है और मज़ाक उड़ाया करने की आवश्यकता है होते हैं। इस लक्ष्य को प्राप्त करने के लिए, हमारी सप्लायर टीम ने एक एपीआई लिखा जो सी ++ मैक्रोज़ के उपयोग के साथ इंटरफेस, रैपर और मैक्स कार्यान्वयन उत्पन्न करता है। आवरण हेडर फाइल के

उदाहरण:

class PlanWrapper : public IPlan 
{ 
    // ... 
    WRP_DECLARE_DEFAULTS(FrameworkPlan); // macro 
    WRP_DECLARE_CSTR_ATTR(FrameworkPlanLabel); // macro 
    // ... 
}; 

मैक्रो WRP_DECLARE_CSTR_ATTR इस तरह परिभाषित किया गया है:

#define WRP_DECLARE_CSTR_ATTR(AttrName) \ 
    virtual bool set##AttrName (LPCTSTR Value_in); \ 
    virtual bool get##AttrName (CString& Value_out); \ 
    virtual bool unset##AttrName(); \ 
    virtual bool isSet##AttrName() 

आवरण cpp फ़ाइल का उदाहरण:

#include "StdAfx.h" 

using namespace SomeNamespace; 

WRP_IMPLEMENT_MODDICOM_DEFAULTS(FrameworkPlan) 
WRP_IMPLEMENT_W_CSTR_ATTR (FrameworkPlan,FrameworkType1, FrameworkPlanLabel) 
// ... 

मैक्रो WRP_IMPLEMENT_W_CSTR_ATTR परिभाषित किया गया है इस तरह:

#define WRP_IMPLEMENT_W_CSTR_ATTR(ClassName,AtrTypeObj,AttrName) \ 
    bool ClassName##Wrapper::set##AttrName (LPCTSTR Value_in) { \ 
      AtrTypeObj aValue = Value_in; \ 
     FrameworkLink<ClassName> convertedObj = NULL_LINK; \ 
     framework_cast(convertedObj, m_Object); \ 
     return convertedObj != NULL_LINK ? \ 
         convertedObj->set##AttrName (aValue) : false; \ 
    } 
    // ... 

हमारे पास और भी जटिल सामग्री का एक गुच्छा है, लेकिन मुझे लगता है कि आपको यह विचार मिलता है।

एपीआई के साथ समस्या यह है कि यह बेहद जटिल है, पठनीय नहीं है, डिबग करने योग्य नहीं है और परीक्षण योग्य नहीं है।

हम एक ही लक्ष्य को प्राप्त करने के लिए एक बेहतर तंत्र के साथ आना चाहते हैं। विचार यह था कि हम उन्नत टेम्पलेट्स, टाइपलिस्ट, लक्षण इत्यादि जैसे नए कंपाइलर के साथ आए कुछ उन्नत फीचर्स का उपयोग करते हैं।

टेम्पलेट्स के साथ हम लगभग अपना लक्ष्य प्राप्त कर सकते हैं, लेकिन हम विधि नामों से फंस गए हैं। हम प्रकारों के लिए सामान्यीकृत कर सकते हैं, लेकिन हम विशेषता नामों से कैसे निपट सकते हैं?

हमने रैपर + इंटरफेस + मैक्स कोड स्वचालित रूप से उत्पन्न करने के लिए टूल बनाने के बारे में भी सोचा। हालांकि, हमारे बाहरी ढांचे का एपीआई बेहद जटिल है और इस तरह के एक उपकरण को लिखना बहुत महंगा होगा।

आपको ऐसी समस्या का समाधान करने का सबसे अच्छा तरीका क्या है? हो सकता है कि आप पहले से ही इस तरह से निपटा चुके हैं और अच्छे संकेत प्रदान कर सकते हैं? हम आपके उत्तरों को देखने की उम्मीद कर रहे हैं!

उत्तर

1

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

इसका तात्पर्य है कि आपके विरासत ढांचे के कोड को पार्स करने का कोई तरीका है। मुझे Clang पर एक नज़र डालेंगी, या शायद स्रोत फ़ाइल पर ctags चलाएं और परिणामस्वरूप टैग का इलाज करें।

+0

Thx। हम निश्चित रूप से क्लैंग और सीटीएजी पर एक नज़र डालेंगे। – nowaq

0

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

+0

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

+0

+1। – umlcat

1

इस समस्या को हल करने के लिए मैक्रोज़ के बजाय सार कारखाने का उपयोग करें।

class IApiFactory{ 
virtual ISomeApi1* getApi1() =0; 
virtual ISomeApi2* getApi2() =0; 
..... 
}; 

अपने सामान्य एपीआई और MOC एपीआई के लिए इस इंटरफेस को लागू करने और की तरह आपके सिस्टम के लिए अपने कारखाने के उदाहरण से पारित करने के बाद:

MySystem system(new NormalApiFactory); 

या

MySystem system(new MocApiFactory); 

आपके सिस्टम घोषित किया जाना चाहिए के रूप में:

class MySystem{ 
public: 
    MySystem(IApiFactory* factory); 
}; 

अपने कारखाने में आप सामान्य एपीआई कार्यान्वयन या एमओसी वस्तुओं को वापस कर देंगे। बेशक आप कारखानों को वापस कर सकते हैं "जो आपके कारखाने से अन्य कारखानों या वस्तुओं को वापस कर देगा"।

+1

लेकिन मुद्दा यह है कि इस पैटर्न में कोड के बड़े बैग को दोबारा कैसे दोहराया जाए .... –

+0

@ बेसिलस्टारनकेविच 'एपीआई के साथ समस्या यह है कि यह बेहद जटिल है, पठनीय नहीं है, डिबगबल नहीं है और टेस्टेबल नहीं है।' 'हम एक ही लक्ष्य को प्राप्त करने के लिए एक बेहतर तंत्र के साथ आना चाहते हैं। विचार यह था कि हम उन्नत टेम्पलेट्स, टाइपलिस्ट, लक्षण इत्यादि जैसे नए कंपाइलर के साथ आए कुछ उन्नत विशेषताओं का उपयोग करते हैं। मैं बस इस समस्या को हल करने के लिए एक मानक तंत्र का सुझाव देता हूं। – AlexTheo

+0

@AlexTheo क्षमा करें, शायद वर्णन थोड़ा उलझन में हो सकता है। "एपीआई" कहकर मेरा मतलब मैक्रोज़ था जिसका हम वर्तमान में रैपर उत्पन्न करने के लिए उपयोग करते हैं। यह "समस्या" है जिसे हम कुछ अच्छे/बेहतर/अधिक मजबूत के साथ प्रतिस्थापित करना चाहते हैं। – nowaq

0

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

0

हमारे DMS Software Reengineering Toolkit एक प्रोग्राम रूपांतरण उपकरण है जो स्रोत कोड पढ़ता है और उस पर मनमानी परिवर्तन करता है।

डीएमएस, इसके C++ Front End (वीसी 6 और अधिक आधुनिक विजुअल स्टूडियो सक्षम) के साथ, इसका उपयोग शायद घटकों के लिए शीर्षलेख फ़ाइलों को पढ़ने के लिए किया जा सकता है, और मैक्स उत्पन्न कर सकते हैं।

डीएमएस का उपयोग सी ++ कोड पर बड़े पैमाने पर परिवर्तन करने के लिए किया गया है, विशेष रूप से इंटरफ़ेस परिवर्तन और विभिन्न तरीकों से इंटरफेस को घुमाने में शामिल किया गया है। मेरे तकनीकी कागजात में से एक देखें, Re-engineering C++ Component Models Via Automatic Program Transformation

0

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

http://blogs.msdn.com/b/t4/archive/2011/11/30/some-nice-new-getting-started-with-t4-videos.aspx

: -

आप दृश्य स्टूडियो (2005 में कम से कम है, लेकिन अधिमानतः 2008 या 2010) आप structurized कोड पीढ़ी के इस टी -4 टीम के उल्लेख किया जिस तरह से उपयोग कर सकते हैं का उपयोग करते हैं कि टी -4 और केवल एक्सएमएल पर आधारित है

मैं अन्वेषक और कि ADM पद्धति के नेतृत्व वास्तुकार और उस ब्लॉग http://abstractiondev.wordpress.com/

दुर्भाग्य से मैं तुम्हारा मैच के लिए लिंक करने के लिए ठोस मामला नहीं है के लेखक हूँ, लेकिन मैं (और आप के लिए समाधान काम करने में खुशी में हूँ यदि आप समुदाय को लाभान्वित करना चाहते हैं, तो उस से एक केस प्रकाशित करें)।