In Scala, how would I give a Singleton a constructor?
Asked Answered
K

3

10

My design incorporates a small database abstraction, whereby I implement each database as a Singleton (well, an object), with custom methods on the database for the couple of operations the code calls (it's mainly a log parser, dumping interesting statistics to a database).

I'd like to construct the Singleton database classes if possible, such that at runtime, each is constructed with config values (and those values remain constant for the remainder of the program's runtime). This would allow me to better test the code too (as I can mock the databases using Mockito or some such).

I'm still only learning Scala, but it seems there's no way to attach a constructor to a Singleton, and would appreciate any input on this problem - is there a better way to do what I'm doing? Is there some preferred way of constructing a Singleton?

Cheers in advance for any help.

Kornegay answered 27/6, 2010 at 23:35 Comment(0)
M
15

Just put the constructor code in the body of the object definition:

object Foo {
    println("Hello") // This will print hello the first time
                     // the Foo object is accessed (and only
                     // that once).
}
Monophony answered 27/6, 2010 at 23:41 Comment(4)
Thanks heaps for the speedy response. My concern with that is that I want to pass arguments to the constructor. Thinking back on it though, I'm realising what a dirty hack that is. I'll need to reconsider my design.Kornegay
Yes its a hack. Singletons are global state, and the point of Scala is to allow invisible parallel processing. This means you can not have global state.Ellmyer
@frio, it might be significant to remember that the object constructor (body) is not executed until you make reference to the object or it's contents (fields or methods) which gives you some measure of control over the construction of the object.Ideatum
@fishtoprecords, the objective is to allow invisible parallel processing - I want various log processing Actors to access a global database instance, so I thought Singleton was a good fit (rather than each tracking the database separately). However, for testability, I want the Singleton to be instantiated with a particular config (so instead of a connection, I can pass it a mock). I think, now, I'd be better off letting each Actor talk to the database individually. It'd be good if I could figure out some way to share a connection pool, but it's not really critical. Thanks for the input :).Kornegay
A
3

Rather than use a singleton (which is hard to test).. Whoever's creating the actors could create a database session factory and pass it to each actor, then it's still shared... and testable.

Audette answered 28/6, 2010 at 3:27 Comment(1)
That's not a bad idea at all. I think the way I've settled on is an individual DB abstraction class for each Actor (instead of a shared Singleton), and yeah, passing it a Factory on startup (although I thought Scala would help me leave a few GoF patterns behind ;)). Thanks Nigel.Kornegay
H
0

Not sure if this if this is what you're looking for but as the article explains, use the apply method without extending the base class

case class Foo(name:String)
object Foo { def apply(name:String) = new Foo(name) }

enter link description here

Haematoblast answered 13/6, 2015 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.