2013-06-15 14 views
19

Supponiamo che io sono un trait a Scalaconvenzione di denominazione di Scala per i tratti

trait Connection { 

    def init(name: String) 
    def dispose 
} 

E voglio creare una classe che implementa. Ma voglio nominarlo come Connection anche:

class Connection extends Connection { 
    // .... 
} 

Non è andare a lavorare. Ovviamente, potrei nominare lo trait in modo diverso, ma ho scoperto che la convenzione di denominazione in Scala dice che dovrei nominare i tratti come classi ordinarie, ovvero senza prefisso, che userei in C# (IConnection dove IConnection sarebbe il interface) .

E in questo caso particolare il nome di Connection per class e trait è più adatto.

Oppure mi sono perso qualcosa nella convenzione di denominazione di Scala?

risposta

10

Il fatto che si stia generando un'API generale in un tratto di tipo Connection implica che avrà più implementazioni specifiche. Tali implementazioni saranno ovviamente correlate ad alcune entità più specifiche, ad es. un database MySQL o H2.

Ci sono diversi approcci al problema a seconda della architettura scelta della vostra applicazione:

  1. Se si mantengono le implementazioni specifiche nello stesso spazio dei nomi si ottiene:

    • myApp.Connection

    • myApp.MySqlConnection

    • myApp.H2Connection

  2. ma quanto sopra è in realtà scoraggiato grazie alla ridondanza nei nomi (parte *Connection) e l'introduzione di un nuovo pacchetto è raccomandato, ad esempio:

    • myApp.Connection

    • myApp.connections.MySql

    • myApp.connections.H2

    o

    • myApp.Connection

    • myApp.Connection.MySql

    • myApp.Connection.H2

    se si sceglie di posizionare l'implemntation specifica in un oggetto compagna di Connection.

  3. In approcci più avanzati per l'architettura si finirà con le implementazioni specifiche che presentano pacchetti privati:

    • myApp.Connection

    • myApp.mySql.Connection

    • myApp.h2.Connection

    E anche qui, anche se si ha il nome Connection scontrandosi è facilmente risolvibili a causa di tipi di essere situati in diversi pacchetti utilizzando i riferimenti qualificati (myApp.Connection) o importazioni qualificati:

    import myApp.{Connection => GeneralConnection} //or IConnection if you insist 
    
+2

Penso che l'opzione 1 sia la più comune nella pratica. L'opzione 2 è confusa quando stai leggendo il codice. – monkjack

+1

@monkjack Esatto; Potrebbe sembrare di ripetere le stesse informazioni ma d'altra parte non ci si può aspettare che tutti gli sviluppatori abbiano tutto il contesto del pacchetto di tutti i tipi nella loro testa. – AlexG

4

La pratica comune per la denominazione di classe che implementa qualche interfaccia/tratto è quello di aggiungere Impl come suffisso (e non aggiungere prefissi/suffissi di interfaccia/tratto):

class ConnectionImpl extends Connection { 
    // .... 
} 

Perché? Perché in buona codice che write functions against interfaces, in modo da non inquinare le funzioni con thoose I di:

def sendThings(conn: Connection) { 


} 

contro

def sendThings(conn: IConnection) { 


} 

Se si dispone di più implementazioni, questo, ovviamente dovrebbe essere Connection tratto, HttpConnection classe 1, JdbcConnection class2.

+3

'HttpUtilImpl',' UserImpl', 'CarImpl' ...?cioè, dovrei aggiungere "Impl" a ciascun nome di classe nel mio codice, anche se non esiste alcun tratto con il nome simile? Non è affatto ragionevole. –

+0

@MariusKavansky no, solo se esiste una situazione * trait e una classe * e non differiscono nei nomi. –

+0

è la stessa cosa. come ho detto nella mia domanda, potrei nominare il tratto (o la classe) in modo diverso, ma non volevo farlo. –

6

Nel libro di Martin Odersky c'è un esempio con una classe Rectangle che estende un tratto Rectangular e una classe Rational che estende un tratto Ordered. Quindi il modello sembra essere quello di usare un aggettivo per il nome del tratto e un soggetto per il nome della classe. Quindi nel tuo caso sarebbe "class Connection extends Connected". Almeno mi piace più di "classe ConnectionImpl estende la connessione".

+4

Forse Connection estende Connectable. Potrebbe non essere sempre connesso. –

6

Non è una convenzione, ma qualcosa di usato nel scala.collection è il suffisso come usato in tratti:

  • SeqLike: Un tratto modello per le sequenze di tipo Seq [A].
  • MapLike: un tratto di modello per le mappe, che associa le chiavi ai valori.

E così via.

Suppongo che sia il loro modo di dire Rettangolo/Rettangolare dove questa relazione (Seq/SeqLike) non ha una denominazione chiara.

Problemi correlati