2010-01-06 15 views
9

कई अवसरों में मेरे पास ऐसे कार्यों का संग्रह है जिन्हें मैं विभिन्न तरीकों से कार्यान्वित करना चाहता हूं। इसका सबसे स्पष्ट उदाहरण विशिष्ट डेटाबेस से सार होना होगा। एक वस्तु उन्मुख भाषा में आप इसके लिए इंटरफ़ेस का प्रयोग करेंगे:क्लोजर में सार फ़ंक्शन या फ़ंक्शन इंटरफेस?

interface DB { 
    ResultSet query(String query); 
    void persist(Object o); 
    ... 
} 

speudo कोड में मैं इस तरह कुछ करना चाहता हूँ होगा: प्रत्येक डेटाबेस के लिए

(ns dbbackend) 

(abstractfn query [q]) 
(abstractfn persist! [o]) 

और फिर कार्यान्वयन:

(ns dbbackend.mysql :implements dbbackend) 
(defn query [q] ...) 
(defn persist! [o] ...) 

यह मेरे लिए बिल्कुल स्पष्ट नहीं है कि एक कार्यात्मक भाषा, विशेष रूप से क्लोजर में कुछ ऐसा करने का सबसे अच्छा अभ्यास क्या है। क्या मुझे इसके लिए बहु-तरीकों का उपयोग करना चाहिए?

+0

बहुआयामी मेरे लिए एक उचित अच्छे मैच की तरह दिखते हैं, शायद एकमात्र। लेकिन मैं क्लोजर पर कोई विशेषज्ञ नहीं हूं इसलिए मैं एक "असली" उत्तर स्वयंसेवक नहीं करूंगा। अच्छे प्रश्न के लिए +1, हालांकि! रोचक जानकारी के लिए –

उत्तर

11

अब version 1.1 of Clojure जारी किया गया है शायद यह भविष्य में देखने का समय हो गया है।

Datatypes और protocols, जो वर्तमान में केवल the new master branch on github में उपलब्ध हैं, वही हो सकता है जो आप खोज रहे हैं।

(defprotocol DB 
    (query [backend query]) 
    (persist [backend object])) 

(deftype MySQLBackend [] 
    DB 
    (query [query] ...) 
    (persist [object] ...)) 
+1

+1, लेकिन ouch, मेरे दिमाग दर्द होता है! क्लोजर तेजी से बढ़ रहा है, मैं इसे सीख सकता हूं :( –

+0

मैंने उन लोगों के बारे में पढ़ा, लेकिन माना कि वे अधिकतर अनुकूलन (क्लोजर इत्यादि में क्लोजर) थे। हालांकि वे यहां भी फिट बैठते हैं। धन्यवाद। –

6

पूर्व प्रोटोकॉल Clojure संस्करणों के लिए:

इंटरफ़ेस:

(ns dbbackend) 

(defmulti query 
    {:arglists '([c q])} 
    suitable-dispatch-fn) 

(defmulti persist! 
    {:arglists '([c o])} 
    suitable-dispatch-fn) 

कार्यान्वयन:

(ns dbbackend.mysql 
    (:requires dbbackend)) 

(defmethod query com.mysql.jdbc.Connection 
    [c q] 
    ...) 

(defmethod persist! com.mysql.jdbc.Connection 
    [c o] 
    ...) 

उपयोग:

(ns user 
    (:require dbbackend dbbackend.mysql)) 

(def mysql-connection (connect-to-mysql)) 
(query mysql-connection some-query) 

आप ClojureQL के हुड के तहत इस दृष्टिकोण का असली दुनिया का उदाहरण पा सकते हैं।

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