2011-03-18 6 views
7

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

+0

किस प्रकार का सत्र? क्या आप एक समस्या और समाधान की तलाश में हैं जिसे एक घंटे, एक दिन, एक हफ्ते में समझाया जा सकता है? कई संभावनाएं हैं। –

+0

हमारे पास नई प्रौद्योगिकियों को प्रदर्शित करने के लिए एक कंपनी व्यापक नियमित शोकेस कार्यक्रम है। यह सत्र पर 2h हाथ के रूप में इरादा है। – spa

उत्तर

12

उदाहरण के एक जोड़े Clojure प्रयोग करने के लिए तर्क का एक बहुत संगामिति के अपने को संभालने के लिए संबंधित दिखाई है, लेकिन मुझे लगता है कि इस मुद्दे को स्पर्श नहीं करेगा यहाँ।

मैं कुछ समस्याओं की सूची दूंगा जिन्हें मुझे सप्ताह में सौदा करने के लिए मजबूर किया जाता है, सप्ताह के साथ जावा और क्लोजर में उन्हें कैसे हल किया जाता है या हल किया जाता है।

अचल स्थिति

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

final Person person = personDao.getById(id); 
// I would like to "change" the person's email, but no setters... :(

Clojure में आप अपरिवर्तनीय डेटा संरचनाओं तो अपने वस्तुओं के सभी डिफ़ॉल्ट रूप से है और इस Clojure के कारण अपरिवर्तनीय हैं के आधार पर अपने डेटा मॉडल शक्तिशाली कार्य करता है जो इन संरचनाओं पर काम करता है।

(let [person   (get-by-id person-dao id) 
     person-with-email (assoc person :email email)] 
    ; Use person-with-email... 

रूपांतरण

जावा में आप क्षेत्रों id, name, email, socialSecurityNumber और अन्य लोगों के साथ एक डोमेन वर्ग Person है। आप अपने डेटाबेस में सभी व्यक्तियों के नाम और ईमेल पुनर्प्राप्त करने के लिए एक वेब सेवा बना रहे हैं। आप अपने डोमेन का पर्दाफाश नहीं करना चाहते हैं ताकि आप कक्षा name और email बना सकें। यह आसान था, इसलिए अब आपको Person से PersonDto पर डेटा मैप करने के लिए फ़ंक्शन की आवश्यकता है। शायद इस तरह कुछ:

public class PersonPopulator { 
    public PersonDto toPersonDto(Person person) { 
     return new PersonDto(person.getName(), person.getEmail()); 
    } 

    public List<PersonDto> toPersonDtos(List<Person> persons) { 
     List<PersonDto> personDtos = new ArrayList<PersonDto>(); 
     for (Person person : persons) { 
      personDtos.add(toPersonDto(person)); 
     } 
     return personDtos; 
    } 
} 

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

(defn person-with-fields [person & fields] 
    (reduce #(assoc %1 %2 (get person %2)) {} fields)) 

(person-with-fields {:id 1 
        :name "John Doe" 
        :email "[email protected]" 
        :ssn "1234567890"} :name :email) 
; -> {:email "[email protected]", :name "John Doe"} 

और व्यक्तियों की एक सूची में हेरफेर करने के:

(map #(person-with-fields % :name :email) persons) 

इसके अलावा एक तदर्थ डेटा जोड़ने

Clojure, अपरिवर्तनीय डेटा संरचनाओं के साथ एक गतिशील टाइप किया भाषा, मुझे यह करने के लिए अनुमति देता है व्यक्ति आसान होगा:

(assoc person :tweets tweets) 

और यह कुछ भी तोड़ नहीं देगा। जावा में यदि आपकी ऑब्जेक्ट्स अपरिवर्तनीय हैं तो उनके पास शायद सेटर्स नहीं हैं, इसलिए आपको केवल एक फ़ील्ड को संशोधित करने के लिए बहुत सारे बॉयलरप्लेट लिखना होगा (new Person(oldPerson.getName(), oldPerson.getEmail(), tweets)), या पूरी तरह से नई कक्षा बनाएं। उत्परिवर्तनीय वस्तुएं एक अच्छी एपीआई (oldPerson.setTweets(tweets)) प्रदान करती हैं, लेकिन परीक्षण और समझना मुश्किल होता है।

परीक्षण

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

क्लोजर कोडिंग करते समय मैंने देखा है कि मुझे वास्तव में इतना अधिक राज्य की आवश्यकता नहीं है। बहुत ही एकमात्र स्थितियां तब होती हैं जब मैं "बाहर" से कुछ प्राप्त कर रहा हूं, चाहे वह डेटाबेस हो या कुछ वेब सेवा हो।

सारांश

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

+0

वाह, महान उदाहरण। – defhlt

+0

मुझे सारांश पसंद आया। क्लोजर के साथ तीन महीने तक काम करते हुए मुझे कैसा लगा। –

1

कुछ महीने पहले मैं एक ही समस्या में भाग गया और हमने क्लोजर में 'मोना लिसा' समस्या को हल करने का फैसला किया। परिणाम this presentation था। असल में हमने दिखाया कि क्लोजर उन समस्याओं को हल करने के लिए बेहद अच्छा है जिसके लिए 'डेटा के रूप में कोड' एक सुरुचिपूर्ण समाधान देता है। उदाहरण के लिए जेनेटिक एल्गोरिदम में।

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