3

I think 'object' in Scala is pretty similar to Singleton in Java which is not considered to be a good design practice. Singleton to me is like another way to define global variables which is BAD. I wrote some Scala code like this because it's easy and it works but the code looks ugly:

object HttpServer { // I'm the only HttpServer instance in this program.
  var someGlobalState: State
  def run() {
    // do something
  }
}

I'm trying to avoid doing this. When is it good to define Scala object?

woodings
  • 7,503
  • 5
  • 34
  • 52
  • possible duplicate of [Why are singleton objects more object orientated?](http://stackoverflow.com/questions/4112088/why-are-singleton-objects-more-object-orientated) – kiritsuku Nov 14 '12 at 18:45
  • 1
    var someGlobalState contrives your question. Scala objects don't imply global state or any state at all. – pedrofurla Nov 14 '12 at 19:04
  • 2
    Rule of thumb: `object`s should not have any mutable state. (Can be broken sometimes, but those cases should be handled with suspicion.) – Madoc Nov 15 '12 at 12:22

3 Answers3

10

No. Many Scala-Libraries heavily rely on object.

The main goal of the Singleton-Pattern is that just one instance of the Object can exist. The same holds true for Object.

You may misuse it as global variable but that is not the point.

Object are for example a great place for Factory Methods or a replacement for Modules to hold functions.

Andreas Neumann
  • 10,734
  • 1
  • 32
  • 52
8

Why do you assume that you only want global variables? Global values and methods are really useful. This is most of what you'll use object for in Scala.

object NumericConstant {
  val Pi = 3.1415926535897932385   // I probably will not change....
}

object NumericFunctions {
  def squared(x: Double) = x*x     // This is probably always what we mean...
}

Now, you do have to be careful using global variables, and if you want to you can implement them in objects. Then you need to figure out whether you are being careless (note: passing the same instance of a class to every single class and method in your program is equally problematic), or whether the logic of what you are doing really is best reflected by a single global value.

Here's a really, really bad idea:

object UserCache {
  var newPasswordField: String = "foo bar"
}

Two users change their password simultaneously and...well...you will have some unhappy users.

On the other hand,

object UserIDProvider {
  private[this] var maxID = 1
  def getNewID() = this.synchronized {
    var id = maxID
    maxID += 1
    id
  }
}

if you don't do something like this, again, you're going to have some unhappy users. (Of course, you'd really need to read some state on disk regarding user ID number on startup...or keep all that stuff in a database...but you get the point.)

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • 1
    I think having an Object like the UserIDProvider in your example is not a good approach. It exposes this object to anyone. You can manipulate the global state maintained in this object at anywhere in your code. Sometimes I'm lazy and don't want to think too hard about who will need to access this object, I'll just define them as singletons. I can access them at anytime later without changing anything. But I believe it's a good practice to limit the object scope to be as minimal as possible. – woodings Nov 14 '12 at 23:24
  • 1
    @woodings - That depends on the scope of the application. If it's something that really cares about new user IDs--maybe it's a new account server--then global is fine. If it's a tiny part of some huge system, then no, you probably don't want it visible everywhere. However, the right way to fix the problem is--if this really is a single global concern--to use access restrictions on a singleton. If you try to mimic it by only instantiating one of an object, you might make a mistake and create two. This way the compiler takes care of it for you. So, `private[whatever] object` it. – Rex Kerr Nov 14 '12 at 23:32
4

Global variables are not inherently bad. You just need to understand when it's appropriate. And so it follows that object is not inherently bad. For example:

object HelloWorld {
  def main(args:Array[String]){
     println("Hello World")
  }
}

Without going into a long discussion of the topic, I like to think of it this way: "Do I want 'only one' of these things because that best reflects reality? Or is this a lazy shortcut to get things to 'just work'?"

Don't just blindly and broadly apply the "Singleton is bad" rule. There are plenty of cases where "just one" of something makes sense. In your particular case, I'd need more context to give a more specific recommendation.

Larsenal
  • 49,878
  • 43
  • 152
  • 220
  • Yes, you have to be careful about testing. There are lots of areas where global things can get you into trouble. For a relative beginner, it's (arguably) pretty easy to create a testing nightmare even without singletons. Comes with experience. – Larsenal Nov 14 '12 at 18:58