2011-10-26 7 views
7

वहाँ Clojure में डेटा मॉडल को लागू करने के लिए कई तरीके होने लगते हैं:एक डाटा मॉडल को लागू करने को रोकने के लिए आम त्रुटियों

  • साधारण में निर्मित डेटाटाइप्स (नक्शे/सूचियों/सेट/वैक्टर)
  • में निर्मित डेटाटाइप्स + मेटा डेटा - उदाहरण के लिए: (type ^{:type ::mytype} {:fieldname 1})
  • निर्मित डेटाटाइप्स + विशेष एक्सेसर कार्यों (उदाहरण के लिए, get टिंग नक्शे से न के बराबर कुंजी एक अपवाद फेंकता है, के बजाय चुपचाप nil लौटने)
  • deftype
  • defstruct
  • defrecord
  • defprotocol

हम बिंदु है जहां नक्शे/सूचियों अब हमारे लिए अच्छी तरह से काम कर रहे हैं पहुँच गए हैं - हम त्रुटियों की बहुत सारी में चलाने है कि पूर्व की स्थिति/पोस्ट हालात आसानी से पकड़ सकते हैं, लेकिन अन्यथा शिकार करने में बहुत लंबा समय लगता है (और नेस्टेड मानचित्र/सूचियों/वैक्टरों को स्वीकार करने वाले कार्यों के लिए प्रभावी पूर्व/पोस्ट-स्थितियां लिखना मुश्किल है) - लेकिन हमें यकीन नहीं है कि उपर्युक्त में से कौन सा है में से चुनना।

हम तीन प्रमुख लक्ष्य हैं:

  • लिखने मुहावरेदार Clojure कोड
  • से बचने के समय की बड़ी मात्रा में खर्च करने के साथ/refactor कोड बदलने की हमारी क्षमता में बेवकूफ प्रकार त्रुटियों
  • विश्वास है नीचे शिकार चुपचाप कुछ भी तोड़ना

हम क्लोजर की शक्ति का उपयोग कैसे कर सकते हैं हमें elp?

उत्तर

4

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

रचनाकारों पर निर्भर। यह एक ओओपी तरह से थोड़ा गंदा लगता है, लेकिन एक कन्स्ट्रक्टर एक ऐसे फ़ंक्शन से अधिक कुछ नहीं है जो आपके डेटा प्रकार को सुरक्षित और आसानी से बनाता है। सादा डेटा संरचनाओं की कमी यह है कि वे फ्लाई पर डेटा बनाने को प्रोत्साहित करते हैं। तो, कॉल करने के बजाय (myconstructor ...), मैं अपने डेटा को सीधे लिखने का प्रयास करता हूं। और त्रुटि के लिए बहुत अधिक संभावनाओं के साथ-साथ समस्याएं अगर मुझे अंतर्निहित डेटा प्रकार को बदलने की आवश्यकता है।

रिकॉर्ड्स मीठा स्थान हैं। कच्चे डेटा प्रकारों के बारे में सभी झगड़े के साथ, यह भूलना आसान है कि रिकॉर्ड बहुत सी चीजें करते हैं जो मानचित्र कर सकते हैं। उन्हें उसी तरह से पहुंचा जा सकता है। आप उन पर seq कॉल कर सकते हैं। आप उन्हें उसी तरह से नष्ट कर सकते हैं। एक मानचित्र की अपेक्षा रखने वाले कार्यों का विशाल बहुमत भी एक रिकॉर्ड स्वीकार करेगा।

मेटा डेटा आपको सहेज नहीं पाएगा। मेटा डेटा पर भरोसा करने के लिए मेरा मुख्य आपत्ति यह है कि यह समानता में प्रतिबिंबित नहीं होता है।

user> (= (with-meta [1 2 3] {:type :A}) (with-meta [1 2 3] {:type :B})) 
true 

चाहे कि स्वीकार्य है या है आप पर निर्भर नहीं है, लेकिन मैं इस नए सूक्ष्म कीड़े को शुरू करने के बारे में चिंता होगी।


अन्य dataype विकल्प:

  • deftype केवल नए बुनियादी या विशेष उद्देश्य डेटा संरचनाओं बनाने में निम्न स्तर के काम के लिए है। Defrecord के विपरीत, यह इसके साथ सभी क्लोजर भलाई नहीं लाता है। अधिकांश कार्यों के लिए, यह आवश्यक या सलाह नहीं है।
  • डिफ्रैक्ट को बहिष्कृत किया जाना चाहिए। जब रिच हिकी ने प्रकार और प्रोटोकॉल पेश किए, तो उन्होंने अनिवार्य रूप से कहा कि defrecord को हमेशा पसंद किया जाना चाहिए।

प्रोटोकॉल बहुत उपयोगी होते हैं, भले ही वे (कार्यों + डेटा) प्रतिमान से एक प्रस्थान का एक सा की तरह लग रहा है। यदि आप खुद को रिकॉर्ड बनाते हैं, तो आपको प्रोटोकॉल को परिभाषित करने पर विचार करना चाहिए।

संपादित: यदि आप वेब प्रोग्रामिंग कर रहे हैं, सादा डेटाटाइप्स करने से और कुशलता से और आसानी से JSON से परिवर्तित किया जा सकता: मैं सादे डेटाटाइप्स कि पहले मेरे लिए स्पष्ट नहीं किया गया था के लिए एक और लाभ की खोज की। (ऐसा करने के लिए पुस्तकालयों में clojure.data.json, clj-json, और मेरे पसंदीदा, चेशर शामिल हैं)। रिकॉर्ड और डेटाटाइप के साथ, कार्य काफी परेशान है।

+0

ठीक है, इसलिए मुझे 'defrecord' और' defprotocol' को समझने की आवश्यकता है, 'defstruct' को अनदेखा कर सकते हैं, और 'deftype' के बारे में ज्यादा चिंता करने की आवश्यकता नहीं है। क्या यह एक क्लोजर प्रोग्राम के लिए महत्वपूर्ण है, कि 'defrecord' जावा कोड बनाता है - इस अर्थ में कि मैं जावा क्लास रखने की चिंता नहीं करना चाहता, लेकिन अगर क्लोजर एक निजी तौर पर उपयोग करना चाहता है, तो यह ठीक है? महान जवाब, बहुत ही हंसमुख। –

+0

ठीक है, एक सादा नक्शा एक जावा क्लास भी है, जैसा कि आप https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java –

+0

पर देख सकते हैं तो यह वास्तव में नहीं है एक बड़ा सौदा है कि defrecord एक जावा वर्ग बनाता है। रिकॉर्ड का उपयोग करके हमारे दृष्टिकोण से, इससे कोई फर्क नहीं पड़ता - निर्माण के अलावा, यह पूरी तरह से क्लोजर डेटा की तरह महसूस करेगा। –

1

यह वास्तव में नक्शे और सूचियों पर काम करने वाले कार्यों को लिखने में सक्षम होने के लिए दृढ़ है, और कक्षाओं और प्रोटोकॉल पर स्विच करके इसे खोने के लिए शर्म की बात होगी। आखिरकार एक प्रकार पर एक सौ कार्य करना बेहतर होता है। प्रोटोकॉल या रिकॉर्ड पर स्विचिंग थोड़ा भारी हाथ होगा। उदाहरण के लिए डीबगिंग करते समय यह (debug (map :rows (get-state)) से आपको रोक देगा।

मेटा डेटा उन स्थानों पर अपने डेटा को सुरक्षित बनाने के लिए "बस पर्याप्त प्रकार" जोड़ने का एक शानदार तरीका है, जो आपके शेष कोडबेस में लाभ खोने के साथ इसकी आवश्यकता है। मैं विकल्प के साथ 2

  • जा रहा सिफारिश करेंगे 'में निर्मित डेटाटाइप्स + मेटा डेटा ({: प्रकार :: MyType} (प्रकार^{: FIELDNAME 1}))'
+0

क्या यह नहीं है कि एक डेटाटिप पर एक सौ कार्य एक एलन पर्लिस-आईएसएम है? मैंने शीर्षक में उस उदाहरण को दोबारा सुधार दिया - गलती से इसे गैर-LISP कोष्ठक में रखा! –

+0

हाँ, यह उद्धरण है कि मैं जिस जा रहा था, क्रेडिट जहां क्रेडिट देय है! –

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

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