Reputation: 26008
Suppose I have a trait
in Scala
trait Connection {
def init(name: String)
def dispose
}
And I want to create a class which implements it. But I want to name it as Connection
also:
class Connection extends Connection {
// ....
}
It's not going to work. Of course, I could name trait
something differently, but it turned out that the naming convention in Scala says that I should name trait as ordinary classes, meaning without any prefix, which I would use in C# (IConnection
where IConnection
would be the interface
).
And in this particular case the name of Connection
for the class
and the trait
is more suitable.
Or did I miss something in Scala's naming convention?
Upvotes: 28
Views: 11634
Reputation: 475
It's not a convention but something used in the scala.collection is the suffix Like used in traits:
And so on.
I guess it's their way to say Rectangle/Rectangular where this relation (Seq/SeqLike) does not have a clear naming.
Upvotes: 11
Reputation: 1585
In Martin Odersky's book there is a sample with a class Rectangle that extends a trait Rectangular and a class Rational that extends a trait Ordered. So the pattern seems here to be to use an adjective for the trait name an a subject for the class name. So in your case it would be "class Connection extends Connected". At least I like this more than "class ConnectionImpl extends Connection".
Upvotes: 8
Reputation: 43309
The fact that you are extracting a general API into a Connection
trait itself implies that it'll have multiple specific implementations. Those implementations will of course be related to some more specific entities, e.g. a MySQL or an H2 database.
There are several approaches to your problem depending on the chosen architecture of your app:
If you keep the specific implementations in the same namespace you get:
myApp.Connection
myApp.MySqlConnection
myApp.H2Connection
But the above is actually discouraged due to redundancy in names (the *Connection
part) and introduction of a new package is recommended, e.g.:
myApp.Connection
myApp.connections.MySql
myApp.connections.H2
or
myApp.Connection
myApp.Connection.MySql
myApp.Connection.H2
if you choose to place the specific implemntation in a companion object of Connection
.
In more advanced approaches to architecture you will end up with specific implementations having private packages:
myApp.Connection
myApp.mySql.Connection
myApp.h2.Connection
And even here although you have the Connection
name clashing it's easily solvable due to types being located in different packages by using qualified references (myApp.Connection
) or qualified imports:
import myApp.{Connection => GeneralConnection} //or IConnection if you insist
Upvotes: 18
Reputation: 62835
The common practice for naming class that implements some interface/trait is to add Impl as postfix (and don't add any prefixes/postfixes to interface/trait):
class ConnectionImpl extends Connection {
// ....
}
Why? Because in good code you write functions against interfaces, so you wont polute your functions with thoose I's:
def sendThings(conn: Connection) {
}
versus
def sendThings(conn: IConnection) {
}
If you have multiple implementations, this, of course should be Connection
trait, HttpConnection
class1, JdbcConnection
class2.
Upvotes: 5