2010-09-01 17 views
5
  1. qual è lo scopo dei namespace?A cosa servono i namespace? che dire degli usi?

  2. e, cosa più importante, dovrebbero essere usati come oggetti in java (cose che hanno dati e funzioni e che cercano di ottenere l'incapsulamento)? questa idea è inverosimile? :)

  3. o dovrebbero essere utilizzati come pacchetti in java?

  4. o dovrebbero essere utilizzati più in generale come un sistema di moduli o qualcosa del genere?

risposta

7

Dato che si utilizza il tag Clojure, suppongo che sarete interessati a una risposta Clojure-specifica:

qual è lo scopo di spazi dei nomi?

Clojure namespace, pacchetti Java, Haskell/Python/qualunque moduli ... a un livello molto elevato, sono tutti nomi diversi per lo stesso meccanismo di base il cui scopo primario è quello di evitare scontri in nome non banale basi di codice. Naturalmente, ogni soluzione ha i suoi piccoli colpi di scena e stranezze che hanno senso nel contesto di una determinata lingua e non avrebbero senso al di fuori di essa. Il resto di questa risposta tratterà i colpi di scena e le stranezze specifiche di Clojure.

Un Clojure gruppi namespace Vars, che sono contenitori funzioni di ritenuta (più spesso), funzioni macro (funzioni utilizzate dal compilatore per generare macroexpansions di forme appropriate, normalmente definiti con defmacro, in realtà sono funzioni solo regolare Clojure, anche se c'è un po 'di magia nel modo in cui sono registrati con il compilatore) e occasionalmente vari "parametri globali" (ad esempio, clojure.core/*in* per input standard), Atomi/Rif. ecc. La funzionalità del protocollo introdotta in Clojure 1.2 ha la proprietà che i protocolli sono supportati da Vars, così come le singole funzioni del protocollo; questa è la chiave per il modo in cui i protocolli presentano una soluzione al problema dell'espressione (che tuttavia è probabilmente fuori dallo scopo di questa risposta!).

È ovvio che gli spazi dei nomi dovrebbero raggruppare Vars in qualche modo correlati. In generale, la creazione di uno spazio dei nomi è un'operazione rapida a basso costo, quindi è perfettamente (e in effetti usuale) utilizzare un singolo spazio dei nomi nelle fasi iniziali dello sviluppo, quindi quando emergono blocchi indipendenti di funzionalità, trascinateli nel loro spazio dei nomi, risciacquare & ripetere ... Solo le cose che fanno parte dell'API pubblica devono essere distribuite tra i namespace in primo piano (o meglio: prima di una versione stabile), dal momento che la funzione tal-e-tale risiede nello spazio dei nomi so- e-così è ovviamente una parte dell'API.

e, cosa più importante, dovrebbero essere usati come oggetti in java (cose che hanno dati e funzioni e che cercano di ottenere l'incapsulamento)? questa idea è inverosimile? :)

Normalmente, la risposta è no. Potresti ottenere un'immagine non troppo lontana dalla verità se ti avvicini a loro come classi con molti metodi statici, senza metodi di istanza, senza costruttori pubblici e spesso senza stato (anche se occasionalmente potrebbero esserci "membri di dati di classe" sotto forma di Vars con Atomi/Rifiuti); ma probabilmente potrebbe essere più utile non provare ad applicare metafore Java-ish agli idiomi Clojure e ad avvicinarsi a uno spazio dei nomi come un gruppo di funzioni ecc. e non "una classe che detiene un gruppo di funzioni" o qualcosa del genere.

C'è un'eccezione importante a questa regola generale: spazi dei nomi che includono :gen-class nel loro modulo ns. Questi sono pensati precisamente per implementare una classe Java che può essere successivamente istanziata, che potrebbe avere metodi di istanza e stato per istanza, ecc. Si noti che :gen-class è una funzionalità di interoperabilità: il codice Clojure puro dovrebbe generalmente evitarlo.

o dovrebbero essere utilizzati come pacchetti in java?

Essi servono alcuni degli stessi scopi per cui i pacchetti sono stati progettati per servire (come già menzionato sopra); l'analogia, sebbene sia certamente lì, non è poi così utile, solo perché le cose che i pacchetti raggruppano insieme (classi Java) non sono affatto come le cose che Clojure namespaces raggruppa insieme (Clojure Vars), i vari "livelli di accesso" (private/package/public in Java, {:private true} o meno in Clojure) funzionano molto diverso ecc

detto, si deve ricordare che c'è una certa corrispondenza tra namespace ei pacchetti/classi risiedono in particolare pacchetti. Un namespace chiamato foo.bar, quando compilato, produce una classe chiamata bar nel pacchetto foo; ciò significa, in particolare, che i nomi degli spazi dei nomi dovrebbero contenere almeno un punto, in quanto i cosiddetti nomi di un singolo segmento sembrano portare a classi nel "pacchetto predefinito", che porta a tutti i tipi di stranezza. (Per esempio.Trovo impossibile avere preavviso profiler di VisualVM eventuali funzioni definite nel namespace singolo segmento.)

Inoltre, deftype/defrecord tipi -Creato non risiedono in spazi dei nomi. Un modulo (defrecord Foo [...] ...) nel file in cui è definito lo spazio nomi foo.bar crea una classe denominata Foo nel pacchetto foo.bar. Per utilizzare il tipo Foo da un altro spazio dei nomi, uno dovrebbe :import la classe Foo dal pacchetto foo.bar - :use/:require non funzionerebbe, dal momento che estraggono Vars da spazi dei nomi, quali record/tipi non lo sono.

Quindi, in questo caso particolare, c'è una certa corrispondenza tra spazi dei nomi e pacchetti che i programmatori Clojure che desiderano sfruttare alcune delle nuove funzionalità linguistiche devono essere a conoscenza. Alcuni ritengono che questo conferisca un "sapore di interoperabilità" a caratteristiche che non sono altrimenti considerate appartenenti al regno dell'interop (defrecord/deftype/defprotocol sono un buon meccanismo di astrazione anche se ci dimentichiamo del loro ruolo nel raggiungere la velocità della piattaforma sulla JVM) ed è certamente possibile che in alcune versioni future di Clojure questo sapore venga eliminato, in modo che il nome spazio/nome del pacchetto corrisponda a deftype & Co. può essere trattato come un dettaglio di implementazione.

o dovrebbero essere utilizzati più in generale come un sistema di moduli o qualcosa del genere?

Essi sono un sistema modulare e questo è davvero il modo in cui devono essere utilizzati.

0

Pensa a loro come contenitori per le tue lezioni. Come se avessi una classe di supporto per la creazione di stringhe e lo avresti voluto nel tuo livello aziendale useresti uno spazio dei nomi come MyApp.Business.Helpers. Ciò consente alle tue classi di essere contenute in posizioni sensoriali, così quando tu o qualcun altro che fa riferimento al tuo codice vuole percepirle possono essere facilmente individuate. Per un altro esempio, se si voleva consumare una classe di connessione di supporto SQL si sarebbe probabilmente usare qualcosa come:

MyApp.Data.SqlConnectionHelper sqlHelper = new MyApp.Data.SqlConnectionHelper();

In realtà si dovrebbe usare un "tramite" l'istruzione in modo che non avrebbe bisogno di qualificare completamente lo spazio dei nomi solo per dichiarare la variabile.

Paul

2

Un pacchetto in Java ha il suo spazio dei nomi, che fornisce un raggruppamento logico di classi. Inoltre, aiuta a prevenire le collisioni di denominazione. Ad esempio in java troverai java.util.Date e java.sql.Date - due diverse classi con lo stesso nome differenziate per il loro spazio dei nomi. Se provi un'importazione sia in un file java, vedrai che non verrà compilato. Almeno una versione dovrà utilizzare il suo spazio dei nomi esplicito.

1

Da una vista indipendente dal linguaggio, gli spazi dei nomi sono un modo per isolare le cose (vale a dire incapsulare in un senso). È un concetto più generale (vedi gli spazi dei nomi xml per esempio). Puoi "creare" spazi dei nomi in diversi modi, a seconda della lingua che usi: pacchetti, classi statiche, moduli e così via. Tutto ciò fornisce spazi dei nomi agli oggetti/dati/funzioni che contengono. Ciò consente di organizzare meglio il codice, di isolare le funzionalità, tende ad un migliore riutilizzo del codice e adattabilità (come l'incapsulamento) Come affermato nello "Zen di Python", "I Namespace sono una delle grandi idee - facciamo più di quelle!" .

Problemi correlati