2009-09-03 18 views
10

Desidero fornire più implementazioni di un lettore/scrittore di messaggi. Qual è l'approccio migliore?quale design dell'interfaccia libreria clojure è il migliore?

Ecco alcuni pseudo-codice di quello che sto attualmente pensando:

  • sono solo un insieme di funzioni che tutte le implementazioni devono fornire e lasciarlo fino al chiamante di trattenere il diritto flussi

    (ns x-format) 
    (read-message [stream] ...) 
    (write-message [stream message] ...) 
    
  • ritorno una mappa con due funzioni chiusi aggrappato al flusso

    (ns x-format) 
    (defn make-formatter [socket] 
        {:read (fn [] (.read (.getInputStream socket)))) 
        :write (fn [message] (.write (.getOutputStream socket) message)))}) 
    
  • qualcos'altro?

risposta

8

Penso che la prima opzione sia migliore. È più estensibile, a seconda di come questi oggetti verranno utilizzati. È più semplice aggiungere o modificare una nuova funzione che funziona su un oggetto esistente se le funzioni e gli oggetti sono separati. In Clojure di solito non ci sono molte ragioni per raggruppare le funzioni insieme agli oggetti su cui lavorano, a meno che non si voglia veramente nascondere i dettagli di implementazione agli utenti del proprio codice.

Se si sta scrivendo un'interfaccia per la quale si prevedono molte implementazioni, considerare anche l'utilizzo di multimethods. È possibile fare in modo che l'eccezione passi un'eccezione "non implementata" per forzare gli implementatori a implementare la propria interfaccia.

Come ha detto Gutzofter, se l'unica ragione per cui si sta considerando la seconda opzione è consentire alle persone di non dover digitare un parametro su ogni chiamata di funzione, si potrebbe considerare che tutte le funzioni utilizzino alcune var come socket predefinito oggetto e scrivendo una macro with-socket che utilizza binding per impostare il valore di var. Vedere i metodi di stampa incorporati che utilizzano il valore predefinito di *out* come flusso di output e with-out-str che associa *out* a un writer di stringhe come esempio Clojure.

This article potrebbero interessarti; confronta e contrasta alcuni idiomi OOP con equivalenti Clojure.

3

Penso che il messaggio di lettura e il messaggio di scrittura siano funzioni di utilità. Quello che devi fare è incapsulare le tue funzioni in una (e) macro (e). Vedi 'with-output-to-string' in common lisp per vedere cosa intendo.

Modifica: Quando si utilizza una macro, è possibile avere la gestione degli errori e l'allocazione delle risorse nell'espansione macro.

2

Vorrei andare con la prima opzione e rendere tutte quelle funzioni multimodate.

Problemi correlati