Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala project organization [closed]

How does one organise code in a Scala project?

After years of developing with Java (most of the times using Spring), we're trying to come up with a quick prototype in Scala.

One of the first questions that popped up is: will we just basically use the same package names and code organisation and just write code in Scala?

For example, we're used to have helpers for our entities (AccountHelper, CacheHelper...) and also sometimes we use services too (AccountService...).

ot: Further away we'll also investigate on how to port our maven submodules to sbt, but that's a different story altogether.

like image 644
user1241320 Avatar asked May 20 '13 15:05

user1241320


2 Answers

The answer partly depends on what is most important to you. If you are really serious about the quick prototype part, then as far as the physical file/directory layout, I would just start with one flat file and only start breaking it up when there is enough code to make that awkward. This should at least make global restructuring of your code easier until you get the overall structure right. Scala does not enforce the package:directory, class:file correspondence, and given the conciseness of Scala that can be overkill in many cases anyway. There is nothing to stop you organizing things into multiple packages within the one file before you break it up physically once you have the structure right. Actually breaking the file up when you need to should be very easy then.

You did not say much about what your Helper & Service classes do, but from the naming convention they sound like good candidates for generic (aka parametric) traits or classes. This would allow you to factor out what all the different Helpers have in common (and similarly for Services). They should have a fair bit in common to justify the naming convention. You would then end up using or possibly extending types like Helper[Cache] and Service[Account]. I am also guessing these types will have few instances with rather broad scope and may benefit from being passed around implicitly, making Helper[_] and Service[_] into type classes. It is also possible that you will no longer need Spring at this point, since implicit lookup may give you the dependency injection you need. However, I am just going by a few class names you provided and reading an awful lot into them, so the chances are that I am completely off base here.

Another possibility is that auxiliary classes like Helper & Service are just closures in disguise. This is a fairly common case with such classes in Java. In this case you should just implement them as functions in Scala, but again I am just guessing from the names...

You could also look into the Layer Cake pattern and see if that makes sense for your project.

More information about your project would probably get you better advice than these products of my overactive imagination :).

Hera are some potentially useful links:

  • http://jonasboner.com/real-world-scala-dependency-injection-di/
  • Where does Scala look for implicits?
  • http://www.youtube.com/watch?v=yLbdw06tKPQ
  • https://vimeo.com/20308847
  • http://www.youtube.com/watch?v=YZxL0alO1yc
like image 108
Daniel Mahler Avatar answered Sep 21 '22 12:09

Daniel Mahler


I organize packages in basically the same way, but wind up implementing things differently. When I first started writing scala coming from java it took me a while to get used to a few things:

  • Use companion objects instead of "static"

    class Bla { } object Bla { ... }

  • Forget about "get*", "set*" getters and setters - use val, var - prefer val.

  • Get to know scala.collection., Option, and scala.collection.JavaConversions. - (which provides implicit conversion between java and scala collection types), so you can write code like this:

      class Helper {
          def lookupUser( name:String ):Option[UserInfo]
          ...
       }
    
     val jsonUsers:Seq[String] = 
       Seq( "fred", "mary", "jose" ).flatMap( 
         name => helper.lookupUser( name )
       ).map( info => helper.toJson( info ) )
    

    or

    val jsonUsers:Seq[String] = for ( name <- Seq( "fred", "mary", "jose" );
                                   info <- helper.lookupUser( name )
       ) yield helper.toJson( info )
    

    or

     val jsResult = helper.lookupUser( "fred" ).map( info => helper.toJson( info ) 
                   ).getOrElse( jsErrorRespose )
    

If you feel comfortable with that kind of code, then you have a good start ...

Good luck!

like image 25
Reuben Avatar answered Sep 20 '22 12:09

Reuben