Come rifattorizzare un singleton Java su Clojure?

7

Sto scrivendo un semplice gioco in Java e voglio imparare Clojure, quindi ho deciso di rifattorizzare il mio attuale codice Java su Clojure. Il problema è che ho codificato così tanto nei linguaggi orientati agli oggetti che non riesco a vedere come farlo dal punto di vista funzionale.

Per essere concreti, ho un Map<String, Country> all'interno di una classe singleton a cui è possibile accedere da qualsiasi luogo per ottenere un'istanza Paese, aggiornarla e reinserirla nella mappa. L'ho implementato allo stesso modo in Clojure. Ad esempio, per aggiornare un Paese:

(def countries (do-get-countries))

(defn update-country
    [country]
    (def countries (assoc countries (get country :name) country)))

Inoltre ho creato un defrecord Country , ma in realtà modifico questi record come

(assoc country :name "New name")

Questi due esempi non sembrano idiomatici secondo me. È questo il modo corretto di farlo in Clojure? Se no, come sarebbe più idiomatico?

Grazie in anticipo!

    
posta m0skit0 28.11.2013 - 18:40
fonte

1 risposta

12

Ecco una guida passo passo per passare dal tuo esempio Java a un discreto Clojure:

  1. riconosce che il tuo singleton è solo uno stato globale e mutabile. Il singleton può funzionare bene ma non è necessario. Quindi siamo passati da Java: singleton - > Java: stato globale e mutevole
  2. effettua il refactoring del proprio esempio Java per utilizzare lo stato mutabile locale anziché lo stato mutabile globale, passando la mappa ai metodi che lo modificano. Passiamo quindi da Java: stato globale e mutevole - > Java: locale, mutabile stato
  3. * ora, invece di aggiornare la mappa in modo distruttivo ogni volta, trova / scrivi una libreria Java (come quello che l'implementazione Clojure usa ) che non muta quando si aggiungono / rimuovendo coppie chiave / valore da / per le mappe. Ricorda di restituire valori che sono stati "aggiornati", altrimenti le modifiche non saranno visibili ad altro codice. Quindi siamo appena passati da Java: locale, stato mutabile - > Java: local, immutable state
  4. a questo punto, hai una soluzione FP, ma è codificata in Java. La tua soluzione iniziale di Clojure potrebbe diventare una traduzione quasi 1: 1, ma man mano che impari di più Clojure scoprirai come sfruttare i suoi punti di forza e migliorare e abbreviare il codice. Inoltre, potresti imparare alcuni schemi interessanti per gestire lo stato "mutabile" in modo puramente funzionale. Quindi spetta a te fare il salto da Java: locale, stato immutabile - > Clojure: local, immutable state

Dal punto 3 sopra: uno dei punti principali della FP è "stessa cosa dentro, stessa cosa fuori". Lo stato mutabile distrugge totalmente questo concetto e, con esso, i vantaggi del puro codice. Clojure non ti ti costringe a essere puro, ma certamente lo rende facile da fare. Quindi se vuoi imparare come scrivere un buon codice Clojure, dovrai imparare come evitare (la maggior parte) lo stato mutabile ad un certo punto.

    
risposta data 03.12.2013 - 12:14
fonte

Leggi altre domande sui tag