Scala的特征命名约定

时间:2013-06-15 08:44:28

标签: scala

假设我在Scala中有trait

trait Connection {

  def init(name: String)
  def dispose
}

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

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

它不会起作用。当然,我可以用不同的方式命名trait,但事实证明Scala中的命名约定我应该将trait命名为普通类,这意味着没有任何前缀,我将在C#中使用({{1}其中IConnection将是IConnection)。

在这种特殊情况下,interfaceConnection的{​​{1}}名称更合适。

或者我在Scala的命名惯例中遗漏了什么?

4 个答案:

答案 0 :(得分:14)

您将一般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
    

答案 1 :(得分:8)

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

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

等等。

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

答案 2 :(得分:7)

在Martin Odersky的书中,有一个带有Rectangle类的示例,它扩展了一个特性Rectangular和一个扩展特性Ordered的类Rational。因此,这里的模式似乎是使用形容名作为类名的主语。所以在你的情况下,它将是“类连接扩展连接”。至少我喜欢这个,而不是“类ConnectionImpl扩展连接”。

答案 3 :(得分:5)

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

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

为什么呢?因为在良好的代码中你write functions against interfaces,所以你不会用我的代码来判断你的函数:

def sendThings(conn: Connection) {


}

def sendThings(conn: IConnection) {


}

如果您有多个实现,那么当然应该是Connection特征,HttpConnection class1,JdbcConnection class2。