27

假设我trait在 Scala 中有一个

trait Connection {

  def init(name: String)
  def dispose
}

我想创建一个实现它的类。但我也想将其命名为Connection

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

这是行不通的。当然,我可以命名trait不同的东西,但事实证明,Scala 中的命名约定说我应该将 trait 命名为普通类,这意味着没有任何前缀,我将在 C# 中使用它(IConnectionwhere IConnection将是 the interface)。

在这种特殊情况下,Connectionfor theclass和 the的名称trait更合适。

还是我错过了 Scala 命名约定中的某些内容?

4

4 回答 4

16

您将通用 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

    如果您选择将特定实现放在Connection.

  3. 在更高级的架构方法中,您最终会得到具有私有包的特定实现:

    • myApp.Connection

    • myApp.mySql.Connection

    • myApp.h2.Connection

    即使在这里,尽管Connection名称冲突,但由于类型位于不同的包中,使用限定引用 ( myApp.Connection) 或限定导入很容易解决:

    import myApp.{Connection => GeneralConnection} //or IConnection if you insist
    
于 2013-06-15T09:52:25.013 回答
9

这不是惯例,但 scala.collection 中使用的东西是特征中使用的后缀 Like:

  • SeqLike : Seq[A] 类型序列的模板特征。
  • MapLike:映射的模板特征,它将键与值相关联。

等等。

我想这是他们说矩形/矩形的方式,其中这种关系(Seq/SeqLike)没有明确的命名。

于 2015-01-11T00:14:07.420 回答
7

在 Martin Odersky 的书中有一个示例,其中包含扩展特征 Rectangular 的类 Rectangle 和扩展特征 Ordered 的类 Rational。所以这里的模式似乎是对特征名称使用形容词,对类名称使用主题。因此,在您的情况下,它将是“类连接扩展连接”。至少我比“class ConnectionImpl extends Connection”更喜欢这个。

于 2013-08-08T14:39:34.307 回答
5

命名实现某些接口/特征的类的常见做法是将 Impl 添加为后缀(并且不要将任何前缀/后缀添加到接口/特征):

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

为什么?因为在好的代码中,你编写了针对接口的函数,所以你不会用那些 I 来污染你的函数:

def sendThings(conn: Connection) {


}

相对

def sendThings(conn: IConnection) {


}

如果你有多个实现,这当然应该是Connectiontrait, HttpConnectionclass1, JdbcConnectionclass2。

于 2013-06-15T09:21:45.017 回答