2012-07-08 9 views
5

स्कैला के फायदों में से एक यह है कि यह आपको दायरे पर बहुत अधिक नियंत्रण देता है। आप घोंसला कर सकते हैं कार्यों इस तरह:स्कैला शैली: कितनी दूर घोंसला कार्य करना है?

def fn1 = { 
    def fn11 = { 
    ... 
    } 
    def fn12 = { 
    ... 
    def fn121 = { 
     ... 
    } 
    } 
    ... 
    def fn13 = { 
    ... 
    } 
} 

समस्या है कि यहाँ fn1 एक सा डराना देखने के लिए शुरू हो सकता है है। जावा पृष्ठभूमि से आ रहा है, हमें सलाह दी जाती है कि आईडीई में एक "पृष्ठ" पर देखने के लिए पर्याप्त छोटे कार्य रखें।

आप fn1 तर्क के आधार पर से बाहर fn12 लेने के बारे में क्या सोचते हैं: "यह केवल अभी fn1 में प्रयोग किया जाता है, लेकिन यह कहीं वर्ग पर बाद में में और उपयोगी में आ सकते हैं ..."

इसके अलावा, क्या आपको नेस्टेड फ़ंक्शंस कहां रखना है - कोड कहने से पहले या उसके बाद कहां से प्राथमिकता होगी?

उत्तर

5

कुछ पैटर्न हैं जो घोंसले की एक परत का लाभ उठाते हैं।

Recursion, जहां यह कार्यान्वयन विवरण छिपाने के लिए किया है (और दो अलग-अलग शीर्ष स्तर की विधियों को अलग करने की तुलना में क्लीनर है) है:

def callsRecursive(p: Param): Result = { 
    def recursive(p: Param, o: OtherParam, pr: PartialResult = default): Result = { 
    ... 
    } 
} 

स्कोप सुरक्षित नहींं-दोहराने खुद:

def doesGraphics(p: Point) { 
    def up(p: Point): Point = // ... 
    def dn(p: Point): Point = // ... 
    def lf(p: Point): Point = // ... 
    def rt(p: Point): Point = // ... 
    /* Lots of turtle-style drawing */ 
} 

और स्थानीय ब्लॉक के लिए निहित रूपांतरणों की तरह अधिक गूढ़ चालें।

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

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

2

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

0

यह वास्तव में बहुत डरावना दिखता है! आप निजी तरीकों का दायरा ठीक नियंत्रित करना चाहते हैं, तो आप उन्हें

private[scope] def fn12 = { ... } 

जहां scope एक पैकेज है घोषणा कर सकते हैं। आप The busy Java developer's guide to Scala में और पढ़ सकते हैं।

मैं व्यक्तिगत रूप से घोंसले नामित विधियों (def) से बचता हूं, जबकि मुझे अज्ञात कार्यों को घोंसला नहीं लगता है (उदाहरण के लिए, निरंतरता-गुजरने वाली शैली प्रोग्रामिंग में बंद)।

2

यदि आपके पास एक शीर्ष स्तरीय फ़ंक्शन है जैसा कि आप वर्णन करते हैं तो शायद यह बहुत अधिक कर रहा है।

टीडीडी निर्णय में भी मदद करता है यदि यह मामला है: अभी भी सब कुछ आसानी से परीक्षण योग्य है।

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

अंत परिणाम में मैं परिभाषित कार्यों में परिभाषित कार्यों का बहुत सीमित उपयोग करता हूं ... मैंने विधि आकार पर बहुत कठोर सीमा भी डाली: जावा में लगभग 10-15 लाइनें, स्कैला में भी कम, क्योंकि यह कम वर्बोज़ है ।

मैंने आंतरिक कार्यों को बाहरी विधि के शीर्ष पर रखा है, लेकिन यह शायद ही कभी बहुत कम है क्योंकि यह बहुत कम है।

6

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

आपको नेस्टेड फ़ंक्शंस को कोड से पहले रखना होगा या यह आगे संदर्भ है और संकलित नहीं होगा। (वस्तुओं/कक्षाओं में आप उन्हें बाद में रख सकते हैं, लेकिन विधियों में नहीं।)

0

नेस्टेड फ़ंक्शंस उपयोगी हैं (उदाहरण के लिए रिकर्सन में सहायक)। लेकिन अगर वे बहुत अधिक हो जाते हैं तो आपको उन्हें एक नए प्रकार में निकालने और उस पर प्रतिनिधि देने से रोक नहीं है।

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