2010-01-06 5 views
9

여러 가지 경우에 여러 가지 기능을 구현하고 싶습니다. 가장 확실한 예는 특정 데이터베이스에서 추상화하는 것입니다. 각 데이터베이스에 대해Clojure의 추상 함수 또는 함수 인터페이스?

(ns dbbackend) 

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

그리고 구현 :

나는 이런 식으로 뭔가를하고 싶은 것 speudo 코드에서

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

: 객체 지향 언어에서는 이것에 대한 인터페이스를 사용합니다

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

Clojure와 같은 기능 언어에서 비슷한 작업을 수행하는 것이 가장 좋은 방법은 무엇인지 완전히 명확하지 않습니다. 멀티 메소드를 사용해야합니까?

+0

멀티 메소드는 저에게도, 아마도 유일한 것 같습니다. 하지만 저는 Clojure에 대한 전문가가 아니므로 "실제"답변을하지 않겠습니다. +1하지만 좋은 질문입니다. –

답변

11

이제 version 1.1 of Clojure이 출시되었을 예정입니다. 미래를 들여다 볼 시간입니다.

Datatypesprotocols은 현재 the new master branch on github으로 만 사용 가능하며 정확하게 찾고있는 것일 수 있습니다. 사전 프로토콜의 Clojure 버전

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

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

+1 재미있는 정보에 대한,하지만 아야, 내 두뇌가 아파! Clojure는 내가 배울 수있는 것보다 빠르게 성장하고있는 것처럼 보입니다 : ( –

+0

나는 이것들에 대해 읽었지만 대부분 최적화라고 생각했습니다. (Clojure in Clojure). –

6

:

인터페이스 :

(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 내부에서 찾을 수 있습니다.