2010-09-30 10 views
9

PHP और .Net बंद हैं; मैं सोच रहा हूं कि ओओपी और डिजाइन पैटर्न में बंद करने का उपयोग करने के कुछ उदाहरण क्या हैं, और शुद्ध ओओपी प्रोग्रामिंग पर उनके क्या फायदे हैं।ओओपी के बंद होने के कुछ उपयोग क्या हैं?

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

+1

यह शायद समुदाय विकी होना चाहिए। – notJim

+0

मैंने वही बात सोच ली है। यह पृष्ठ: http://php.net/manual/en/functions.anonymous.php का एक उदाहरण है, लेकिन इसे आसानी से बंद किए बिना पुनः लिखा जा सकता है। – Galen

उत्तर

3

क्लोजर ईवेंट-हैंडलिंग के लिए उपयोगी हैं। यह उदाहरण एक सा काल्पनिक है, लेकिन मुझे लगता है कि यह विचार बता देते हैं:

class FileOpener 
{ 
    public FileOpener(OpenFileTrigger trigger) 
    { 
     trigger.FileOpenTriggered += (sender, args) => { this.Open(args.PathToFile); }; 
    } 

    public void Open(string pathToFile) 
    { 
     //… 
    } 
} 

मेरी फाइल सलामी बल्लेबाज या तो सीधे बुला instance.Open(pathToFile) द्वारा एक फ़ाइल खोल सकते हैं, या यह किसी घटना से शुरू हो रहा जा सकता है। अगर मेरे पास अज्ञात फ़ंक्शंस + क्लोजर नहीं हैं, तो मुझे एक ऐसी विधि लिखनी होगी जिसमें इस घटना का जवाब देने के अलावा कोई अन्य उद्देश्य नहीं था।

2

, आप FileOpener उदाहरणों के किसी भी संख्या बनाने की क्षमता के साथ एक वर्ग प्रदान करना चाहते हैं मान लीजिए, लेकिन आईओसी सिद्धांतों का अनुसरण, आप नहीं वर्ग FileOpener रों बनाने वास्तव में ऐसा करने के लिए कैसे (दूसरे शब्दों में जानना चाहते हैं आप new उन्हें नहीं चाहते हैं)। इसके बजाय, आप निर्भरता इंजेक्शन का उपयोग करना चाहते हैं। हालांकि, आप केवल इस वर्ग को FileOpener उदाहरण उत्पन्न करने में सक्षम होना चाहते हैं, न केवल किसी भी उदाहरण के लिए। यहां आप क्या कर सकते हैं:

class AppSetup 
{ 
    private IContainer BuildDiContainer() 
    { 
     // assume this builds a dependency injection container and registers the types you want to create 
    } 


    public void setup() 
    { 
     IContainer container = BuilDiContainer(); 
     // create a function that uses the dependency injection container to create a `FileOpener` instance 
     Func<FileOpener> getFileOpener =() => { return container.Resolve<FileOpener>(); }; 

     DependsOnFileOpener dofo = new DependsOnFileOpener(getFileOpener); 

    } 
} 

अब आपके पास अपनी कक्षा है जिसे फ़ाइलऑपर उदाहरण बनाने में सक्षम होना चाहिए। तुम्हें पता है, इस क्षमता के साथ यह प्रदान करने के लिए निर्भरता इंजेक्शन का उपयोग ढीला संयोजन बनाए रखते हुए

class DependsOnFileOpener() 
{ 
    public DependesOnFileOpener(Func<FileOpener> getFileOpener) 
    { 
     // this class can create FileOpener instances any time it wants, without knowing where they come from 
     FileOpener f = getFileOpener(); 
    } 
} 
3

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

एक ट्रैम्पोलिन एक ऐसा फ़ंक्शन है जो अपने कॉलर को वापस बंद करने के लिए "बाउंस" करता है। बंद "बाकी काम" को पकड़ता है।

उदाहरण के लिए, पायथन में आप एक पुनरावर्ती संचायक एक सरणी में मानों का योग करने को परिभाषित कर सकते हैं:

testdata = range(0, 1000) 
def accum(items): 
     if len(items) == 0: 
       return 0 
     elif len(items) == 1: 
       return items[0] 
     else: 
       return items[0] + accum(items[1:]) 

print "will blow up:", accum(testdata) 

मेरी मशीन पर, यह जब आइटम की लंबाई 998

से अधिक एक ढेर अतिप्रवाह के साथ बाहर क्रेप्स

वही कार्य बंद का उपयोग कर एक ट्रैम्पोलिन शैली में किया जा सकता है:

def accum2(items): 
     bounced = trampoline(items, 0) 
     while (callable(bounced)): 
       bounced = bounced() 
     return bounced 

def trampoline(items, initval): 
     if len(items) == 0: 
       return initval 
     else: 
       return lambda: trampoline(items[1:], initval+items[0]) 

प्रत्यावर्तन परिवर्तित यात्रा करने के लिए, आप ढेर बुझाना नहीं है के द्वारा। जब आप रिकर्सन के साथ करते हैं तो क्लोज़ की बजाय खुद को गणना की स्थिति को कैप्चर करने की संपत्ति होती है।

+0

साफ चाल! मुझे नहीं लगता कि मैंने इसे पहले कभी देखा है। क्या यह पाइथन के साथ सबसे आम है (जो समझाएगा कि मैंने इसे कभी क्यों नहीं देखा है)? – FrustratedWithFormsDesigner

+0

लिस्प दुनिया में यह काफी आम है। अधिकांश लिस्प कार्यान्वयन में, यह वास्तव में संकलक ("पूंछ-कॉल अनुकूलन") द्वारा स्वचालित रूप से किया जाता है।लेकिन कभी-कभी आपको इसे हाथ से करना पड़ता है क्योंकि संकलक केवल विशिष्ट विन्यास में पैटर्न को पहचान सकता है। –

+0

* * * अनिवार्य भाषाओं में आम नहीं है, लेकिन उदा। LEPL (http://www.acooke.org/lepl/) जटिल रिकर्सिव अवरोही पार्सर्स को ढेर से बहने से रोकने के लिए ट्रैम्पोलिनिंग का उपयोग करता है। – delnan

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