2009-03-08 22 views
14

मैं अपने कोल्डफ्यूजन निर्देशिका संरचनाओं को पुनर्गठित कर रहा हूं और इस बारे में उत्सुक हूं कि सीएफ डेवलपर्स छोटे कैफनों के पुस्तकालयों का आयोजन कैसे कर रहे हैं।आप अपने छोटे पुन: प्रयोज्य कैफंक्शन कैसे व्यवस्थित करते हैं?

मैं विस्तृत घटकों (वस्तुओं) के बारे में उत्सुक नहीं हूं क्योंकि मैं छोटे से उपयोगिता कार्यों के दर्जनों के बारे में हूं जो हम सभी समय के साथ बनाते हैं।

  • क्या आप एक बड़ी एकल फ़ाइल का उपयोग करते हैं और इसे शामिल करते हैं?
  • क्या आप एक बड़ी फ़ाइल को एक cfcomponent के रूप में उपयोग करते हैं और creatobject/cfinvoke कहते हैं?
  • क्या आप प्रत्येक यूटिलिटी सीफंक्शन को अपने सीएफसी में डालते हैं और createobject/cfinvoke कहते हैं?
  • क्या आप cfimport taglib वाक्यविन्यास का उपयोग करते हैं?
  • क्या आप कस्टमटैग या cfmodule का उपयोग करते हैं?
  • क्या आपके पास बेहतर तरीका है?

चूंकि मुझे वर्बोज़ सिंटैक्स पसंद नहीं है, इसलिए मैं केवल lib.cfm को cfincluding कर रहा हूं जिसमें इसमें सामान्य cffunctions का गुच्छा है। मैं उन्हें सीएफसी समूहित करने के लिए दोबारा कर सकता हूं, मैं परिवर्तनीय क्षेत्रों पर बेहतर अलगाव के लिए createobject कर सकते हैं।

क्या ऐसा करने का कोई बेहतर तरीका है?

उत्तर

18

यह 13 जून, 2007 को blog post I did का पुनर्मुद्रण है। मैं इस विधि का उपयोग काफी समय से कर रहा हूं और यह बहुत अच्छा काम करता है! YMMV।

उपयोगकर्ता परिभाषित कार्यों (यूडीएफ) को कौन पसंद नहीं करता है? यदि आपने कोई प्रोग्रामिंग किया है, तो संभावना है कि आपने उन्हें बड़े पैमाने पर उपयोग किया है। लोगों के साथ सबसे बड़ी समस्या यह है कि उन्हें अपने आवेदन में कैसे शामिल और व्यवस्थित करना है।

<!--- UDFs.cfc ---> 
<cfcomponent output="false"> 

<cffunction name="init" access="public” returntype="Any" output="false"> 
    <cfreturn this> 
</cffunction> 

<cffunction name="myUDF1" access="public" returntype="Any" output="false"> 
</cffunction> 

<cffunction name="myUDF2" access="public" returntype="Any" output="false"> 
</cffunction> 

</cfcomponent> 

एक बार जब आप:

मैंने पाया क्या कि ज्यादातर लोगों को करना एक Utils.cfc या UDFs.cfc बना सकते हैं और कटौती और उनके UDFs पेस्ट है कि वे घटक में उपयोग करने के लिए नीचे दिखाए चाहते है सभी यूडीएफ हैं कि आपका आवेदन आपके घटक में चिपकाए जाने का उपयोग करेगा, आपको यूडीएफ को आपके आवेदन में उपलब्ध कराने की आवश्यकता होगी। मैंने जो भी देखा है, वह घटक द्वारा एप्लिकेशन स्कोप में लोड हो रहा है। यदि आप Application.cfc उपयोग कर रहे हैं निम्नलिखित लाइन onApplicationStart() में रखा जाता है या सिर्फ Application.cfm में जोड़कर आपको लगता है कि उपयोग कर रहे हैं:

<cfset application.functions = CreateObject("component", "udfs").init()> 

जो भी एक का उपयोग कर रहे, Application.cfc या Application.cfm, परिणाम समान हैं; आपके सभी यूडीएफ आपके आवेदन के लिए उपलब्ध हैं और आप उन्हें पूरी तरह से उपयोग कर सकते हैं। केवल अंतर यह है कि आप किस वैरिएबल नाम का उपयोग करते हैं। मैं आवेदन का उपयोग करता हूं। क्रियाएं, कुछ एप्लिकेशन.टिल या application.udfs का उपयोग करें; कोई फर्क नहीं पड़ता, फिर से, परिणाम एक ही हैं।

वहाँ एक समस्या मैं हालांकि इस दृष्टिकोण के साथ है, यह बोझिल है है और UDFs घटक विशाल मिल जाएगा। ऐसी विशाल घटक फ़ाइल रखने में समस्या संपादन कर रही है, यह कोड की हजारों लाइनों के माध्यम से स्क्रॉल करने के बाद से एक दुःस्वप्न बन गया है, यह बहुत मजेदार नहीं है और मैंने देखा है कि सीएफईक्लीप्स बड़ी फाइलों पर नीचे गिरता है। निश्चित कोड पतन कुछ राहत प्रदान करता है लेकिन एक बेहतर तरीका होना चाहिए।

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

पूरा करने के लिए मैं चाहता था, मैं कोड के 11 लाइनों के लिए मेरी UDFs.cfc संशोधित:

<!--- UDFs.cfc ---> 
<cfcomponent output="false"> 

    <cfset variables.udfdir = GetDirectoryFromPath(GetCurrentTemplatePath()) & "udfs"> 
    <cfset variables.q = ""> 

    <cffunction name="init" access="public" returntype="Any" output="false"> 
    <cfreturn this> 
    </cffunction> 

    <cfdirectory action="list" directory="#variables.udfdir#" filter="*.cfm" name="variables.q"> 

    <cfoutput query="variables.q"> 
    <cfinclude template="udfs\#name#"> 
    </cfoutput> 

</cfcomponent> 

तो क्या वास्तव में चल रहा है?

संक्षेप में, यहां क्या हो रहा है: मेरे पास एक ही निर्देशिका में udfs नामक एक निर्देशिका है जो मेरे पास UDFs.cfc है। यह वह निर्देशिका है जिसे मैंने अपनी सभी यूडीएफ सीएफएम फाइलों को रखा है। UDFs.cfc क्या करता है जब यह कॉल किया जाता है तो इस निर्देशिका को स्कैन किया जाता है और स्वचालित रूप से प्रत्येक सीएफएम फ़ाइल को पाता है। इस प्रकार यह यूडीएफ फ़ोल्डर में स्वचालित रूप से किसी भी यूडीएफ को लोड करता है (आमतौर पर "मिश्रण" कहा जाता है)।

तो मेरा लक्ष्य तक पहुँच जाता है! मेरे पास प्रत्येक यूडीएफ की अपनी फाइल में है इसलिए मुझे इसे खोजने के लिए एक विशाल घटक फ़ाइल को स्क्रॉल करने की आवश्यकता नहीं है। अब मैं इसे आसानी से खोल और संपादित कर सकता हूं। निर्देशिका को देखकर, मुझे पता है कि मेरा आवेदन किस यूडीएफ का उपयोग कर रहा है। मैं निर्देशिका में ब्राउज़र से पाठ को केवल निर्देशिका में सहेजकर CFLib.org से स्वचालित रूप से एक यूडीएफ जोड़ सकता हूं। इसके अलावा यदि मुझे अब मेरे आवेदन में यूडीएफ का उपयोग करने की आवश्यकता नहीं है, तो मैं निर्देशिका से फ़ाइल को हटा देता हूं और इसे अगले एप्लिकेशन में मेरे एप्लिकेशन से निकाल दिया जाता है। यह सब मुख्य UDFs.cfc फ़ाइल को छूए बिना किया जाता है।

नीचे यूडीएफ CFM फ़ाइलों में से एक की तरह लग रहा है की एक उदाहरण है। फ़ाइल को fullLeft.cfm कहा जाता है और यूडीएफ निर्देशिका में रहता है।

<!--- fullLeft ---> 
<cffunction name="fullLeft" access="public" displayname="fullLeft" returntype="string" output="false"> 
    <cfargument name="str" type="string" required="true"> 
    <cfargument name="count" type="numeric" required="true"> 
    <cfif not refind("[[:space:]]", arguments.str) or (arguments.count gte len(arguments.str))> 
    <cfreturn Left(arguments.str, arguments.count)> 
    <cfelseif reFind("[[:space:]]",mid(arguments.str,arguments.count+1,1))> 
    <cfreturn left(arguments.str,arguments.count)> 
    <cfelse> 
    <cfif count-refind("[[:space:]]", reverse(mid(arguments.str,1,arguments.count)))> 
     <cfreturn Left(arguments.str, (arguments.count-refind("[[:space:]]", reverse(mid(str,1,arguments.count)))))> 
    <cfelse> 
     <cfreturn left(arguments.str,1)> 
    </cfif> 
    </cfif> 
</cffunction> 
+0

बहुत अच्छा विचार, मुझे आपके दृष्टिकोण के साथ प्रयोग करना होगा। – kevink

+0

मैं अच्छे परिणामों के साथ लंबे समय से ऐसा कर रहा हूं। –

+1

मैंने कल इसे लागू किया और कहना है कि यह बहुत अच्छा काम करता है। मैंने निर्देशिका के माध्यम से लूपिंग करके अपने यूनिट परीक्षणों को सरल बनाने के दृष्टिकोण का भी उपयोग किया, इस प्रकार यह सुनिश्चित कर लें कि कोई भी कार्य याद नहीं किया जा सके। बहुत चालाक – kevink

1

मुझे लगता है कि यह आपकी प्रोग्रामिंग शैली पर निर्भर करता है, जिस भी शैली के साथ आप सबसे अधिक आरामदायक हैं। मुझे लगता है सबसे आसान तरीका है application.cfm में, मेरे सभी उपयोगिता कार्यों के साथ एक cfcomponent करने के लिए आवेदन के दायरे में एक चर सेट है:

<cfif not isDefined("application.utilities")> 
    <cfset application.utilities = createObject("component", "Utilities")> 
</cfif> 

अब आप कहीं से भी application.utitlies में तरीकों कॉल कर सकते हैं। ध्यान दें कि यदि आप अपने cfcomponent में परिवर्तन करते हैं, तो आपको अपने एप्लिकेशन वैरिएबल को यूटिलिटीज के नए इंस्टेंस के साथ रीफ्रेश करना होगा।

+0

शायद इसे 'param application.utilities = createObject ("घटक", "उपयोगिताएं") के रूप में लिखा जा सकता है; ' –

1

आप Application.cfc (यदि आप नहीं कर रहे हैं मैं दृढ़ता से Application.cfm से यह की ओर पलायन सुझाव है - अपने करने के लिए बहुत आसान) प्रयोग कर रहे हैं आप अपने सभी यूडीएफ के तरीकों के साथ एक baseComponent.cfc निर्माण कर सकते हैं और baseComponent से Application.cfc उत्तराधिकारी है। फिर onRequestStart विधि में एक चर सेट करें जिसे request.app = यह कहा जाता है;

entiure अनुरोध के लिए

, आप तो यूडीएफ का उपयोग करने की request.app.methodname() का उपयोग कर सकते हैं। UDFs

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

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

hth जॉन

1

हम समारोह पुस्तकालयों के लिए .cfm फ़ाइलों का उपयोग और cfinclude साथ उचित फ़ाइल कहते हैं। कुछ .cfm फ़ाइलों को cflib.org से डाउनलोड किया गया है और अन्य हमारे द्वारा लिखे गए हैं। फाइलें यूडीएफ नामक निर्देशिका में हैं जो कि दूसरी निर्देशिका की एक उपनिर्देशिका है जिसे आगे स्लैश वर्ण में मैप किया गया है। Cfinclude कथन बस है:

<cfinclude template="/UDF/filename.cfm"> 

यह दृष्टिकोण सर्वर पर सभी अनुप्रयोगों के लिए उपलब्ध कार्यों को बनाता है।

हम कई छोटे पुस्तकालय दृष्टिकोण भी पसंद करते हैं। प्रत्येक लायब्रेरी विषय विशिष्ट (गणित, स्ट्रिंग, सूची सरणी आदि)

+0

दिन के अंत में आप कितनी छोटी फाइलें समाप्त कर रहे हैं? –

0

विकल्प है: आप cffunctions के साथ एक बड़े एकल फाइल उपयोग करें और यह cfinclude है?

एक: मुझे लगता है कि किया है लेकिन मैं इसे और कम से कम करते हैं। मैं विरासत और cfcexplorer

विकल्प का लाभ लेने पसंद: यदि आप एक cfcomponent के रूप में एक बड़ी एकल फाइल का उपयोग करते हैं और कहते हैं creatobject/cfinvoke?

उत्तर: हाँ मैं अक्सर इस

विकल्प कार्य करें: आप अपने स्वयं के सीएफसी में प्रत्येक उपयोगिता cffunction रख दिया और फोन CreateObject/cfinvoke है?

एक: आप cfimport taglib सिंटैक्स का उपयोग करें: अगर मैं उम्मीद अतिरिक्त कार्य बाद में

विकल्प जोड़े जाने के लिए मैं यह कर सकता है?

एक: आप CustomTags

एक का उपयोग करें:: मैं i18n सामान कि जिस तरह से

ऑप्शन कर एक लंबे समय में नहीं। या cfmodule: सीएफसी के इस

विकल्प में बेहतर कर रहे हैं?

ए: लंबे समय तक नहीं। इस पर सीएफसी बेहतर है। फोन करने वाले। * गुंजाइश मुझे पता है यह एक पुराने सवाल है, लेकिन मैं इन मुद्दों के लिए एक अलग दृष्टिकोण का एक छोटा सा का उपयोग यह मुश्किल

0

डिबग करने के लिए कर सकते हैं।

उपयोगिता समारोह/'इंजेक्शन'

साथ सिंगलटन दृष्टिकोण मैं एक 'कोर' या 'उपयोगिता' सीएफसी पैदा करते हैं।

  • बार-बार इस तरह के एक सामान्य viewRecord() दाव और एक कोर checkSecurity() समारोह, एट अल के रूप में हर समय हर जगह (प्रयोग किया है: इसमें मैं अपने सभी उपयोगिता प्रकार कार्यों कि कर रहे हैं पैक।)
  • आधार कार्य है कि imho सीएफ में मुख्य होना चाहिए रहे हैं (जैसे lpad(), capitalize(), एट अल)
  • कुछ टैग (जैसे exit() के रूप में जो <cfexit> लपेटता मुझे सर्वत्र cfscript उपयोग करने के लिए)
अनुमति रैपर हैं

onApplicationStart() पर, मैं इस ऑब्जेक्ट का एक उदाहरण बनाता हूं और इसे Application स्कोप पर असाइन करता हूं जिससे इस प्रकार एक स्थिर सिंगलटन बनता है।

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

public/remote any function init() { 
    structAppend(Variables, Application.MyApp.Objects.oCore.injectCoreMethods()); 
    return this; // Return instance of this object 
} 

injectCoreMethods() विधि चुनिंदा उपयोगिता कार्यों मैं लगभग मेरी सभी वस्तुओं में विस्तार चाहते हैं की एक संरचना देता है: मैं उपयोगिता वस्तु पर ही एक विधि ऐसी है कि फोन करके यह करते हैं। यह सभी उपयोगिता विधियों को अनिवार्य रूप से इंजेक्ट नहीं करता है। injectCoreMethods() समेत कम अक्सर उपयोग किए जाने वाले लोगों को अभी भी पूर्ण सिंगलटन एप्लिकेशन पॉइंटर जैसे Application.MyApp.Objects.oCore.infrequentMethod() के माध्यम से संबोधित करने की आवश्यकता होगी।

Variables गुंजाइश में इंजेक्शन करके, जो सुरक्षित है, ये विधियां प्रभावी ढंग से निजी तरीके होंगी। तो ऑब्जेक्ट्स के किसी भी डंप इन यूटिलिटी फ़ंक्शंस को नहीं दिखाएंगे, लेकिन सीएफसी के भीतर इसकी सभी सीधी तरीकों से पूरी तरह से पहुंच योग्य हैं।

फ़ाइल संगठन:

मैं आम तौर पर फ़ोल्डर प्रति एक सीएफसी होने के पैटर्न में गिर गए हैं। प्रत्येक फ़ोल्डर में, मेरे पास घटक और init के लिए एक सीएफसी फ़ाइल है। सीएफएफ फाइलों में टूटने वाले सभी अन्य तरीकों और उस सीएफसी में शामिल हैं। मैं करने के लिए ऐसा करते हैं:

  1. 1000+ लाइनों जो नीचे मेरी आईडीई धीमा कर सकते हैं की बचें विशाल सीएफसी फ़ाइलें (मैं Aptana/cfeclipse का उपयोग करें)
  2. परिवर्तन दर्ज किया जा/फ़ाइल आधार प्रति एक फ़ाइल के बारे में अधिक कड़ाई से नज़र रखी अनुमति दें और इस प्रकार मेरे एससीएम/संस्करण नियंत्रण सॉफ्टवेयर में दर्ज किया गया।
  3. एक से अधिक व्यक्ति को किसी दिए गए ऑब्जेक्ट पर एक-दूसरे में बंपिंग कोड के साथ काम करने की अनुमति दें।

तो एक दाव वस्तु जो 4 crud तरीकों में शामिल है कुछ इस तरह दिखेगा:

/code/dao/dao.cfc 
/code/dao/_removeRecord.cfm 
/code/dao/_addRecord.cfm 
/code/dao/_viewRecord.cfm 
/code/dao/_editRecord.cfm 

सीएफसी सिर्फ init() और स्वयं का दस्तावेजीकरण गई टिप्पणियां हैं और छद्म निर्माता क्षेत्र में मैं चार में शामिल तरीकों। यह मुझे किसी भी सीएफसी को अपने फ़ोल्डर से पकड़ने और इसे कहीं और स्थानांतरित करने देता है।

उपयोगिता सीएफसी के लिए ही। यह अपने स्वयं के फ़ोल्डर में बैठता है और इसमें 10 या तो सीएफएम फाइलों के बीच लगभग 30 अजीब फ़ंक्शन हैं (कुछ साधारण फ़ंक्शंस जिन्हें मैं उसी फ़ाइल में छोड़ता हूं जैसे कि _string.cfm जिसमें वास्तव में lpad(), rpad() आदि शामिल हैं, सभी स्ट्रिंग संबंधित हैं। आपको विचार मिलता है।)

मॉड्यूल और कस्टम टैग

मैं क्योंकि वे पंजीकृत है और आसान चाल/तैनाती में बाधा होने की जरूरत है हर कीमत पर इन से बचें। मुझे उन चीजों को पसंद नहीं है जो सिर्फ एक पर्यावरण से दूसरे वातावरण में ड्रैग और ड्रॉप पर स्वयं कॉन्फ़िगर नहीं करते हैं। सीएफ 5- आपको इस तरह से बहुत कुछ करना था। लेकिन सीएफ 6 और वास्तविक ओओपी पैटर्न में वस्तुओं का उपयोग करने की क्षमता के बाद, आप क्यों चाहेंगे? ऐसे बहुत कम मामले हैं जिन्हें आप चाहते हैं/यदि कोई हो तो चाहिए।

अन्य

मैं (यह देखने के लिए, एक समारोह और देखा जोड़ने! किंडा के लिए चीजों को जैसे चाहें base.cfc जो स्वचालित रूप से सभी सीएफसी के सीएफ द्वारा उत्पन्न में बढ़ा दिया गया है में 'कोर' कार्यों डाल करने के लिए इस्तेमाल किया जेएस में प्रोटोटाइप)। मुझे वास्तव में यह पसंद था लेकिन यह तैनाती/रखरखाव के लिए एक समस्या थी।

कुछ डिग्री के लिए, मैं एक फैक्टरी दृष्टिकोण लेता हूं। मैं प्रायः मूल रूप से अनुप्रयोग में स्थिर सीएफसी की उचित मात्रा डालता हूं। एक नियंत्रक एक सामान्य नियंत्रण तालिका पढ़ता है और ऐप वैरिएबल जैसे ऐप शुरू होने पर अन्य चीजों के समूह के साथ लूप में सभी ऑब्जेक्ट्स सेट करता है। लेकिन कुछ वस्तुओं को जरूरी, स्पष्ट रूप से भारी वस्तुओं और वस्तुओं के रूप में तत्काल किया जाता है जिनमें उस श्रेणी में छेड़छाड़ करने योग्य [अर्ध] लगातार डेटा गिरता है

मैंने कुछ तरीकों से सीएफ 7 के बाद ऐसा किया है। सीएफ 9 + के साथ यह बहुत आसान, परिपक्व और चिकना हो रहा है।

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