2012-08-26 16 views
5

यह प्रश्न थोड़ा व्यापक और वैचारिक है।किसी अन्य विधि से पहले एक विधि को रोकने के लिए

मेरे पास विभिन्न विधियों के साथ एक कक्षा है। आइए उन्हें A और B पर कॉल करें। मैं कैसे सुनिश्चित कर सकता हूं कि भविष्य में इस कक्षा के साथ काम करने वाले अन्य डेवलपर्स कम से कम एक बार कॉलिंग विधि ए से पहले विधि बी को कॉल नहीं करेंगे?

मैं इसे सी ++ में कर रहा हूं लेकिन आम तौर पर इसे लागू करने का सबसे अच्छा तरीका क्या है? मैंने कुछ विचारों को बेवकूफ बना दिया है जैसे कि बूलियन वैरिएबल का उपयोग करना, लेकिन मैं कुछ अन्य विचार भी सुनना चाहता हूं।

+0

आप वास्तव में आदेश को लागू नहीं कर सकते (आपके पास पहले से ही एक समाधान है)। आप टेम्पलेट पैटर्न के साथ फिर से डिजाइन करने और इस विशेष आवश्यकता से बचने में सक्षम हो सकते हैं। http://en.wikipedia.org/wiki/Template_method_pattern – Jayan

उत्तर

10

इसकी गारंटी देने का एक तरीका? एक बार विधि ए को कॉल करने के लिए विधि बी की ज़िम्मेदारी बनाएं।

कुछ और एक नाजुक एपीआई है।

+1

यह एक अच्छा विचार है (+1), ध्यान दें कि इसका नुकसान यह है कि ए को कॉल करने के लिए आवश्यक सभी जानकारी बी में पारित की जानी चाहिए - यह कर सकता है उदास हो जाना। (कल्पना करें कि आपके सभी डीबी कनेक्शन डेटा को प्रत्येक क्वेरी में पास करने की आवश्यकता है ...) –

+0

इसके अलावा "केवल रास्ता" थोड़ा मजबूत आईएमओ है। –

+0

ठीक है, अच्छे अंक। –

4

एक बूलियन वैरिएबल है जो निर्धारित करता है कि A कहलाता है या नहीं। फिर, जब कोई इस बूलियन चर सेट किए बिना B का आह्वान करने का प्रयास करता है, तो एक IllegalStateException फेंक दें।

या आपके पास B हो सकता है बस A पर कॉल करें क्योंकि ऐसा लगता है कि यह बिना किसी भी तरीके से A को निष्पादित नहीं किया जा सकता है।

अन्यथा, और चूंकि दोनों विधियां सार्वजनिक हैं, इसलिए इसे लागू करने के लिए वास्तव में कोई अन्य तरीका नहीं है।

5

एक बूलियन का उपयोग करना एक अच्छी शुरुआत है, और पहुंच कार्यों पर फेंकना ठीक है।

हालांकि कभी-कभी संकलन-समय पर इसे लागू करने में सक्षम होना अच्छा होता है। उस स्थिति में आपका एकमात्र असली विकल्प कुछ चाल का उपयोग करना है।

केवल अपनी कक्षा में एक का पर्दाफाश, यह एक प्रॉक्सी बी

class MyClass { 
    public: 

    struct BProxy { 
     public: 
     MyClass * root; 
     void B() { root->B(); } 
     protected: 
     BProxy(MyClass * self) : root(self) {}; // Disable construction 
     friend class MyClass; //So that MyClass can construct it 
    }; 

    BProxy A() { ... return BProxy(this); } 
    friend class BProxy; // So that BProxy can call B() 
    protected 
    void B() { ... } 
}; 

int main() { 
    MyClass m; 
    BProxy bp = m.A(); 
    // m.B(); can't do this as it's private - will fail at compile time. 
    bp.B(); // Can do this as we've got the proxy from our previous call to A. 
} 

तुम भी लागू करने (या एक आभासी उपलब्ध कराने)() बी एक baseclass से संरक्षित विरासत का उपयोग कर कुछ इसी तरह प्राप्त कर सकते हैं लौटाएगा बनाते हैं।

5

एक तरीका है अपनी कक्षा को थोड़ा अलग तरीके से फिर से डिजाइन करना। एक साधारण डेटाबेस वर्ग पर विचार करें जिसे इस्तेमाल होने से पहले शुरू किया जाना चाहिए। मैं जावा लड़का हूं, इसलिए ...

public class Database { 
    public void init(String username, String password) // must call this first! 
    public List<Object> runQuery(String sql) // ... 
} 

तो मुझे पहले init कॉल करने की आवश्यकता है। मैं डेटाबेसफैक्टरी बना सकता हूं जो प्रारंभिकता करता है और वास्तविक डेटाबेस ऑब्जेक्ट देता है। हम कन्स्ट्रक्टर को छुपा सकते हैं ताकि केवल डाटाबेस फैक्टरी डाटाबेस बना सके (जावा में एक नेस्टेड क्लास, सी ++ में एक दोस्त क्लास हो सकता है?)।

public class DatabaseFactory { 
    public Database init(String username, String password) // ... 

    public class Database { 
    private Database() {} 
    public List<Object> runQuery(String sql) // ... 
    } 
} 

तो अब मुझे अंतर्निहित वस्तु प्राप्त करने के लिए फैक्ट्री के माध्यम से जाना होगा।

DatabaseFactory factory = new DatabaseFactory(); 
Database database = factory.init("username", "password"); // first init (call method A) 
// now I can use database (or B in your case) 
database.runQuery("select * from table"); 
2

यह गारंटी देने का एक तरीका यह है कि A कक्षा के निर्माता में किया जाता है। यदि कन्स्ट्रक्टर विफल रहता है (फेंकता है) तो अन्य डेवलपर्स के पास कुछ गलत नहीं है जो कि B के साथ गलत है। यदि कन्स्ट्रक्टर सफल होता है तो A कम से कम एक बार किया जाता है और इसलिए B करने के लिए वैध ऑपरेशन है।

2

मैं ऑब्जेक्ट को आरंभ करने के लिए "ए" कन्स्ट्रक्टर विधि बनाउंगा। इसे संकलक द्वारा लागू वस्तु का उपयोग करने के लिए एक बार बुलाया जाना है।बाद में आप ज्ञान में एक विधि "बी" कह सकते हैं जिसे एक निर्माता को बुलाया जाना चाहिए था।

संबंधित मुद्दे