2013-06-15 2 views
19

Предположим, что я есть в Scalaименовании Scala для черт

trait Connection { 

    def init(name: String) 
    def dispose 
} 

в trait И я хочу, чтобы создать класс, который реализует его. Но я хочу, чтобы назвать это как Connection также:

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

Это не будет работать. Конечно, я мог бы назвать trait что-то по-другому, но оказалось, что соглашение об именах в Scala говорит, что я должен назвать черту как обычные классы, то есть без префикса, который я бы использовал в C# (IConnection, где IConnection был бы interface) ,

И в этом конкретном случае больше подходит название Connection для class и trait.

Или я пропустил что-то в соглашении об именах Scala?

ответ

10

Тот факт, что вы извлекаете общий API в собственный признак Connection, подразумевает, что он будет иметь несколько конкретных реализаций. Конечно, эти реализации будут связаны с некоторыми более конкретными объектами, например. базу данных MySQL или H2.

Есть несколько подходов к вашей проблеме в зависимости от выбранной архитектуры вашего приложения:

  1. Если вы сохраняете конкретные реализации в том же пространстве имен вы получите:

    • myApp.Connection

    • myApp.MySqlConnection

    • myApp.H2Connection

  2. Но выше на самом деле не рекомендуется из-за избыточности имен (*Connection часть) и введение нового пакета рекомендуется, например,:

    • myApp.Connection

    • myApp.connections.MySql

    • myApp.connections.H2

    или

    • myApp.Connection

    • myApp.Connection.MySql

    • myApp.Connection.H2

    , если вы решите разместить конкретный implemntation в компаньона объекта из Connection.

  3. В более продвинутых подходов к архитектуре вы будете в конечном итоге с конкретных реализаций, имеющих частные пакеты:

    • myApp.Connection

    • myApp.mySql.Connection

    • myApp.h2.Connection

    И даже здесь, хотя у вас есть Connection имя сталкиваясь это легко решаемая из-за типа расположены в разных пакетах с помощью квалифицированных ссылки (myApp.Connection) или квалифицированных импорт:

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

Я думаю, что вариант 1 является наиболее распространенным на практике. Вариант 2 запутан, когда вы читаете код. – monkjack

+1

@monkjack Правильно; Может показаться, что повторяется одна и та же информация, но, с другой стороны, вы не можете ожидать, что у всех разработчиков будет весь контекст пакета всех типов в их голове. – AlexG

4

Обычная практика для обозначения класса, который реализует некоторый интерфейс/черт добавить Impl, как постфикс (и не добавлять префиксы/postfixes для интерфейса /): черт реальных

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

Почему? Потому что в хорошем коде вы write functions against interfaces, поэтому вы не polute свои функции с thoose я ':

def sendThings(conn: Connection) { 


} 

против

def sendThings(conn: IConnection) { 


} 

Если у вас есть несколько реализаций, это, конечно, должно быть Connection черта, HttpConnection class1, JdbcConnection класс2.

+3

'HttpUtilImpl',' UserImpl', 'CarImpl' ...?то есть я должен добавить 'Impl' в каждое имя класса в моем коде, даже если нет признака с похожим именем? Не разумно. –

+0

@ MariusKavansky nope, только если есть * свойство и один класс * ситуация, и они не отличаются по именам. –

+0

это то же самое. как я сказал в своем вопросе, я мог бы назвать черту (или класс) по-другому, но я не хотел этого делать. –

6

В книге Одерски в Eсть образец с классом Rectangle, который расширяет черту Rectangular и класс Rational, который расширяет выделенную оценку. Таким образом, шаблон, похоже, состоит в том, чтобы использовать прилагательное для имени признака субъекта для имени класса. Поэтому в вашем случае это будет «class Connection extends Connected». По крайней мере, мне нравится это больше, чем «class ConnectionImpl extends Connection».

+4

Возможно, соединение расширяет Connectable. Это может быть не всегда связано. –

6

Это не соглашение, а что-то используется в scala.collection является суффикс Как используется в чертах:

  • SeqLike: Шаблон черта для последовательностей типа Seq [A].
  • MapLike: Шаблонная черта для карт, которые ассоциируют ключи со значениями.

И так далее.

Я думаю, что это их способ сказать Прямоугольник/Прямоугольник, где это отношение (Seq/SeqLike) не имеет четкого названия.

Смежные вопросы