2011-07-05 25 views
8

मैंने भौतिकी विश्लेषण कोड का एक टुकड़ा लिखा है, शुरुआत में अपने लिए, जो उम्मीद है कि भौतिकविदों के एक छोटे समूह द्वारा उम्मीद और विस्तार किया जाएगा। हम में से कोई भी सी ++ गुरु नहीं है। मैंने एक छोटे ढांचे को एक साथ रखा है जो "भौतिकी घटना" डेटा को औजारों की एक श्रृंखला द्वारा क्रियान्वित वस्तुओं में सारणीबद्ध करता है जिसे विश्लेषण आवश्यकताओं के आधार पर आसानी से बाहर और बाहर किया जा सकता है।दोस्ती विरासत में नहीं मिली - विकल्प क्या हैं?

इसने कोड में दो हिस्सों का निर्माण किया है: "भौतिकी विश्लेषण" कोड जो ईवेंट ऑब्जेक्ट्स में हेरफेर करता है और आधार "टूल" के डेरिवेटिव के माध्यम से हमारे परिणाम उत्पन्न करता है; और "संरचनात्मक" कोड जो इनपुट फ़ाइलों को जोड़ता है, नौकरी को समानांतर रनों में विभाजित करता है, कुछ स्क्रिप्ट के अनुसार एक श्रृंखला में लिंक टूल्स इत्यादि।

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

मैं करने में सक्षम होना चाहते हैं:

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

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

दुर्भाग्यवश, इस मामले में आधार से गेटर्स/सेटर्स को कॉल करने की विधि (जो एक दोस्त है) इसे हल करने से अधिक समस्याएं पैदा करेगी - कोड को जितना आसान हो, उतना आसान होना चाहिए, और जैसा कि कनेक्ट किया गया है उपकरण के कार्यान्वयन में जितना संभव हो सके भौतिकी (किसी उपयोगकर्ता को सी ++ या प्रोग्राम बनाने के लिए प्रोग्राम की आंतरिक कार्यप्रणाली में विशेषज्ञ होने की आवश्यकता नहीं है)।

यह देखते हुए कि मेरे पास एक विश्वसनीय आधार वर्ग है और कोई भी डेरिवेटिव निकट जांच के अधीन होगा, क्या कोई अन्य चौराहे है लेकिन इन डेरिवेटिव तक पहुंच की अनुमति देने का अच्छी तरह से परीक्षण किया गया तरीका है? या किसी अन्य आधार के डेरिवेटिव तक पहुंच से इंकार करने का कोई तरीका?


स्थिति स्पष्ट करने के लिए मैं की तरह

class Event 
{ 
    // The event data (particle collections etc) 
}; 

class Tool 
{ 
    public: 
     virtual bool apply(Event* ev) = 0; 
}; 

class ExampleTool : public Tool 
{ 
    public: 
     bool apply(Event* ev) 
     { 
      // do something like loop over the electron collection 
      // and throw away those will low energy 
     } 
}; 

कुछ आदर्श केवल ऊपर दो कारणों (ए और बी) के लिए इन उपकरणों को घटना की सामग्री तक पहुँच को सीमित करना होगा है।

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

+2

यदि कोई भी व्यक्ति जो स्रोत के साथ काम करने या देखने की आवश्यकता नहीं है, तो C++ पर एक विशेषज्ञ है, तो C++ का उपयोग न करें। सी ++ उन लोगों के लिए एक गंदा भाषा है जो विशेषज्ञ नहीं हैं और विशेषज्ञ बनने की संभावना नहीं है, खासकर यदि भारी ओओ तकनीक उपयोग में है। – DarenW

+0

यह परिचित लगता है ... घटना डेटा कौन है या किसके पास है?क्या ये उपयोगकर्ता उपकरण इवेंट डेटा को बदलना चाहते हैं, या नए इवेंट डेटा का उत्पादन करने के लिए इसका इस्तेमाल करते हैं? – juanchopanza

+0

@DarenW, मुझे दृढ़ता से संदेह है कि ओपी के पास कोई विकल्प नहीं है ... – juanchopanza

उत्तर

2

सी ++: public, protected और private में तीन एक्सेस क्वालीफायर हैं। उपकरण आधार वर्ग से पहुँच इनहेरिट व्युत्पन्न भौतिक विज्ञान उपकरणों के साथ वाक्य संकेत मिलता है कि आप protected पहुंच चाहते हैं लगता है, लेकिन यह स्पष्ट नहीं है कि वास्तविक डेटा कि है privateTool में है (और इस प्रकार protected पर्याप्त होता है) या वर्तमान में private है एक वर्ग में Tool मित्रतापूर्ण है।

पहले मामले में, बस डेटा protected बनाने:

class Tool { 
protected: 
    type data; 
}; 

दूसरे मामले में, आप उपकरण स्तर पर एक्सेसर उपलब्ध कराने के उदाहरण के लिए, भाषा पर बुरा चाल खेलने की कोशिश कर सकते हैं,:

class Data { 
    type this_is_private; 
    friend class Tool; 
}; 
class Tool { 
protected: 
    static type& gain_acces_to_data(Data& d) { 
     return d.this_is_private; 
    } 
}; 
class OneTool : public Tool { 
public: 
    void foo(Data& d) { 
     operate_on(gain_access_to_data(d));  
    } 
}; 

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

एक साथ ही सिर्फ नव निर्मित पिछले दरवाजे का उपयोग कर सकते ऐसा करने के लिए डेटा तक पहुंच हासिल करना चाहता है कि उपयोगकर्ता:

struct Evil : Tool { 
    static type& break_rule(Data & d) { 
     return gain_access_to_data(d); 
    } 
}; 

और अब हर किसी के बस Data करने के लिए एक दरवाजे के रूप में Evil उपयोग कर सकते हैं। मैं अनुशंसा करता हूं कि आप C++ पर अधिक अंतर्दृष्टि के लिए C++FAQ-lite पढ़ें।

+0

(+1) किसी प्रोग्राम समस्या का वर्णन करने के लिए, कोड उदाहरण के साथ, भले ही स्पष्ट लगता है ;-) – umlcat

+0

सुझाव के लिए धन्यवाद। ईविल के साथ स्थिति ठीक रहेगी - मेरे पास टूल बेस क्लास में निर्मित ट्रैकिंग और लॉगिंग है और सभी टूल्स और उनकी सेटिंग्स कॉन्फ़िगरेशन स्क्रिप्ट के साथ प्रोग्राम आउटपुट में सहेजी जाती हैं। यदि लॉग टूल्स स्क्रिप्ट से मेल नहीं खाते हैं तो इसका स्पष्ट कोई बुराई है - अगर वे स्क्रिप्ट से मेल खाते हैं तो यह वह करता है जिसे आपने करने के लिए कहा था। लेकिन चेतावनी के लिए धन्यवाद। – Anthony

0

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

-- ToolInterface.hpp -- 
class Event; // just forward declare it 

class ToolStructuralInterface 
{ 
    // only what the structural code needs to invoke tools 
    virtual void invoke(std::list<Event*> &) = 0; 
}; 

-- ToolImplementation.hpp -- 
class Event 
{ 
    // only the tool code sees this header 
}; 
// if you really want to prevent accidental inclusion in the structural code 
#define TOOL_PRIVATE_VISIBILITY 

-- StructuralImplementation.hpp -- 
... 
#ifdef TOOL_PRIVATE_VISIBILITY 
#error "someone leaked tool implementation details into the structural code" 
#endif 
... 

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

2

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