42
votes

I've recently started programming in Scala, coming from Python and Java I was wondering what the correct way or the accepted way is when defining objects/classes in Scala. Scala supports, just like python, to add several class or object definitions in a single file.

So purely from an accepted structure perspective, does every object need to be defined in its own file or are you allowed to choose this yourself?

3
I make exceptions when prototyping, but as soon as code solidifies, I refactor to the standard of sticking to just one class/trait and/or companion object per file. In pretty much every case where I want to define multiple units, as with sealed traits or concrete implementations, it makes sense to contain those in the companion object. So it really comes down to the question: does this other unit reasonably "belong" to the companion object? If not, put it in its own file.acjay

3 Answers

61
votes

There is a chapter in the official Scala Style Guide on this. It's pretty clear in itself, but I'll just leave some quotes here.

The core idea is:

As a rule, files should contain a single logical compilation unit. By “logical” I mean a class, trait or object.

There is, of course, an exception for companion objects:

One exception to this guideline is for classes or traits which have companion objects. Companion objects should be grouped with their corresponding class or trait in the same file.

There is also the fact that sealed only works within the same file.

Despite what was said above, there are some important situations which warrant the inclusion of multiple compilation units within a single file. One common example is that of a sealed trait and several sub-classes. Because of the nature of sealed superclasses (and traits), all subtypes must be included in the same file.

Most of the time, case classes are just simple data containers and can be grouped together.

Another case is when multiple classes logically form a single, cohesive group, sharing concepts to the point where maintenance is greatly served by containing them within a single file.

Finally, there is a naming convention for exempted multi-unit Scala files:

All multi-unit files should be given camelCase names with a lower-case first letter.

So: put your Scala classes and objects in separate files, unless they fall into one of the three mentioned exceptions.

11
votes

In Scala, it is perfectly valid to have multiple classes within a single file AS LONG AS they are tightly related.

But not all languages encourage this convention, and I think it is worth considering the reason.

I personally dislike it when people put multiple classes into a single file because it makes it harder to find a class definition. This is magnified in code reviews where I want to be able to review code as quickly as possible without digging around.

Cons

  1. Code reviews require me to do more searching to find a class
  2. I don't like having to grep to find a file
  3. A consistent naming convention allows me to use my text editor or IDE tools to quickly open a file by the class name

Pros

  1. As Jesper pointed out, certain scenarios require it
  2. Support classes/traits are kept hidden to minimize file structure "noise"
4
votes

Sometimes you have to put several traits, classes or objects in one source file, particularly when you are using sealed traits. A sealed trait can only be extended inside the same source file.