2013-06-15 16 views
19

Angenommen, ich habe eine trait in ScalaScala Namenskonvention für Züge

trait Connection { 

    def init(name: String) 
    def dispose 
} 

Und ich will, um eine Klasse erstellen, die es implementiert. Aber ich will es als Connection nennen auch:

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

Es ist nicht zur Arbeit gehen. Natürlich könnte ich trait etwas anders benennen, aber es stellte sich heraus, dass die Namenskonvention in Scala besagt, dass ich Merkmals als normale Klassen bezeichnen sollte, dh ohne Präfix, das ich in C# verwenden würde (IConnection wo IConnection wäre das interface) .

Und in diesem speziellen Fall ist der Name Connection für die class und die trait besser geeignet.

Oder habe ich etwas in der Namenskonvention von Scala vermisst?

Antwort

10

Die Tatsache, dass Sie eine allgemeine API in eine Connection Eigenschaft extrahieren, bedeutet, dass es mehrere spezifische Implementierungen haben wird. Diese Implementierungen werden natürlich mit einigen spezifischeren Einheiten in Beziehung stehen, z. eine MySQL- oder eine H2-Datenbank.

Es gibt mehrere Ansätze, um Ihr Problem auf der gewählten Architektur Ihrer Anwendung abhängig:

  1. Wenn Sie die spezifischen Implementierungen im gleichen Namensraum halten Sie erhalten:

    • myApp.Connection

    • myApp.MySqlConnection

    • myApp.H2Connection

  2. Aber die oben tatsächlich durch Redundanz in Namen abgeraten (die *Connection Teil) und die Einführung eines neuen Pakets wird empfohlen, z.B.:

    • myApp.Connection

    • myApp.connections.MySql

    • myApp.connections.H2

    oder

    • myApp.Connection

    • myApp.Connection.MySql

    • myApp.Connection.H2

    wenn Sie die spezifische implemntation in einem Begleiter Objekt von Connection zu platzieren.

  3. In fortgeschritteneren Ansätze zur Architektur werden Sie sich mit spezifischen Implementierungen mit privaten Paketen Ende:

    • myApp.Connection

    • myApp.mySql.Connection

    • myApp.h2.Connection

    Und auch hier, obwohl Sie die Connection Namen haben kollidierende sie unter Verwendung qualifizierter Referenzen aufgrund Arten in verschiedenen Paketen angeordnet sind (myApp.Connection) oder qualifizierte Importe leicht auflösbar ist:

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

Ich denke, Option 1 ist in der Praxis am häufigsten. Option 2 ist verwirrend, wenn Sie Code lesen. – monkjack

+1

@monkjack Das ist richtig; Es mag sich anfühlen, die gleichen Informationen zu wiederholen, aber andererseits können Sie nicht erwarten, dass alle Entwickler den gesamten Paketkontext aller Typen im Kopf haben. – AlexG

4

Die gängige Praxis für die Klasse zu benennen, dass Geräte einige Interface/Merkmal Impl als Postfix hinzufügen (und fügen Sie keine Präfixe/Postfix Schnittstelle/Zug):

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

Warum? Da in gutem Code Sie write functions against interfaces, so wie Sie es sonst verschmutzen Ihre Funktionen mit thoose Ich:

def sendThings(conn: Connection) { 


} 

gegen

def sendThings(conn: IConnection) { 


} 

Wenn Sie mehrere Implementierungen haben, dies natürlich sollte Connection Charakterzug, HttpConnection class1 sein, JdbcConnection Klasse2.

+3

'HttpUtilImpl',' UserImpl', 'CarImpl' ...?das heißt, ich sollte jedem Klassennamen in meinem Code "Impl" hinzufügen, auch wenn es keine Eigenschaft mit dem ähnlichen Namen gibt? Überhaupt nicht vernünftig. –

+0

@MariusKavansky Nö, nur wenn es * Merkmal und eine Klasse * Situation gibt und sie unterscheiden sich nicht in Namen. –

+0

das ist das Gleiche. Wie ich in meiner Frage gesagt habe, könnte ich das Merkmal (oder die Klasse) anders benennen, aber das wollte ich nicht. –

6

In Martin Odersky Buch gibt es ein Beispiel mit einer Klasse Rectangle, die ein Merkmal Rectangular und eine Klasse Rational erweitert, die ein Merkmal Ordered erweitert. Das Muster scheint hier also ein Adjektiv für den Objektnamen und ein Subjekt für den Klassennamen zu sein. In deinem Fall wäre es also "Klasse Connection extends Connected". Wenigstens mag ich das mehr als "class ConnectionImpl extends Connection".

+4

Maybe Connection erweitert Connectable. Es ist möglicherweise nicht immer verbunden. –

6

Es ist keine Konvention, sondern in der scala.collection verwendet etwas ist das Suffix wie in Eigenschaften verwendet:

  • SeqLike: Eine Vorlage Merkmal für die Sequenzen des Typs Seq [A].
  • MapLike: Ein Vorlagenmerkmal für Karten, die Schlüssel mit Werten verknüpfen.

Und so weiter.

Ich denke, es ist ihre Art, Rectangle/Rectangular zu sagen, wo diese Beziehung (Seq/SeqLike) keine klare Benennung hat.