views:

232

answers:

4

Every time I come across an implementation of the singleton pattern or any static classes (i.e. classes with (almost) only static members) I wonder whether this isn't actually a hack and therefore heavy abuse of the principle of classes and instances just to design single objects instead of designing classes and creating a single instance. To me, it looks like static members of classes in general try to add some sort of characteristics to classes which they actually aren't supposed to have and which rather make them object themselves.

But is it really desirable to have single objects implemented like that? Or do you see things completely differently and don't think that such static classes or singletons have anything in common with actual objects?

A: 

Say I have an application which has a single configuration file. How would I create functions to operate on that file without the use of a "singleton" if my language does not support global functions outside of a class (like Java or C#)?

It seems to me the only real way to accomplish that is have a singleton class. Using the singleton pattern you also don't need to pass around a pointer to the object, since you can just use the static method to get it again.

I don't see how this is a violation of any OO principles. To do it a different way, like put the configuration functions in another class that doesn't deal with configuration (like a "utility" class) is more of a violation of OO principles.

SoapBox
But isn't it better to pass pointers around to achieve code which is easier to read and maintain? Actually it's the same problem as with global variables yet differently packed. See also http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
codethief
In theory, sure. But even in the example in that article you have exploded the "CreditCard" class constructor to possibly 6 members and this was just a simple example. Having functions with 10+ parameters just to stick to ideology is not a good idea.
SoapBox
Passing all dependencies in through the constructor is just one way to do dependency injection. Another way is setting properties. Yet another alternative is the "service locator" pattern. Classic article: http://www.martinfowler.com/articles/injection.html
Wim Coenen
A service locator completely defeats the purpose, it's basically jsut a singleton wrapper.
SoapBox
+5  A: 

Static members are effectively just namespacing for globals, yes. Nothing wrong with that; namespacing is good, and globals are the cleanest way to accomplish some tasks.

Singletons can be somewhat more interesting (load on demand...) but they're a similar construct (yeah, you could think of a static member as an anonymous singleton managed by the compiler).

Like most things, these tools have their place, and only the ideologues worry about whether or not they "fit" with a particular ideology.

Shog9
A: 

Depending on your language, classes are objects. In ruby and java, they're of class Class; in python, I don't remember (subclasses of type?).

In java, you can't avoid putting things on classes. This means you sometimes have to use classes like you would use namespaces and modules. A lot of the static methods on Math are a good example of this. I'd say that having these methods be static makes the best of a bad situation.

I think whether it's "dirty" to have static attributes depends very much on the context. What you really should look for is proper encapsulation: it's good if you can draw a curve through the conceptual space of your code and say "everything on this side doesn't need to know anything about things on that side, except for the interface across the curve.

Jonas Kölker
Just for the record: in Python, a class object is an *instance* of either classobj (old-style classes) or type (new style classes).
David Zaslavsky
A: 

You can view it from a performance and memory perspective. For example, in the following code:

public class StringUtils
{
    public static boolean isEmpty(String value)
    {
        // some code
    }

    public static String reverseString(String value)
    {
        // some code
    }
}

Do you really want to instantiate StringUtils objects all over the place just to call a method that doesn't store any member variables? In a simple program, it doesn't matter much. But once your program starts to get to a certain size and you call these methods thousands of times, well let's just the instantiations can add up. And why? To be a purist? It's not worth the cost. Just use the same instance.

Stephane Grenier
No, ideally you want these to be methods of String
Patrick Daryll Glandien