5

While working on a project, I decided to create a database class to manage my DB connection. I started looking for the best practice to do that, which is usually either a static class or a singleton pattern class. Answers I've found, such as:

http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

When to use a Singleton and when to use a static class

Favor the singleton approach over the static one, for mostly understandable reasons (easier to make thread-safe, easier to make use of OOP features, easier to test...), but one reason I can't understand is that static classes shouldn't have any kind of state. Could someone explain the reason behind that?

4
  • 4
    Why do you think a singleton or a static class would be a good solution or the best practice?
    – COME FROM
    Commented Dec 10, 2016 at 19:28
  • I have one DB connection and I want it to be a shared resource accessible from multiple parts of my application. Honestly, static or singleton were the most intuitive solutions that made good sense to me. If you have some other suggestions I'd be happy to hear them :) I am using C# btw Commented Dec 10, 2016 at 19:33
  • 2
    Dependency Injection. Inversion of Control. Commented Dec 10, 2016 at 19:41
  • 2
    The question is more likely: Why global states are evil?.
    – Laiv
    Commented Dec 10, 2016 at 20:07

1 Answer 1

5

Why shouldn't a static class have an internal state?

Because, in the context you're linking to, not having internal state is the DEFINITION of a static class.

Here static class doesn't mean static class. It means java.lang.Math. That's a final class full of static methods.

Now that our vocabulary is clear...

@Doval Why shouldn't it? – Aviv Cohn Apr 10 '14 at 14:02

Well...

@Prog Because you're just using global variables in disguise. All parts of your application that make any calls to the static class are now invisibly dependent on each other, and any parts of your application that are dependent on those parts are now indirectly dependent as well, and so on. Mutable state is already a bad idea if you can avoid it. Global mutable state is just a bad idea. – Doval Apr 10 '14 at 14:05

So why

Favor the singleton approach over the static one

Because Murphy was an optimist. You say you only have one DB resource now but suppose that changes?

Designing around the idea that there will only ever be one of anything is forgetting why we solve some problems with keyboards, not soldering irons.

I favor the immutable instance approach (I can't bring myself to say singleton because the GoF singleton pattern is so so so not optimal) because shared mutable state is the real sin.

Give me a way to get an immutable instance that points to the DB resource you want me to talk to and I'll talk to it. Whether it talks to your 1st or 2nd DB resource is none of my business.

That's dependency injection. Counting the number of of DB resources is now a problem pushed out into construction. From there you could push it out to configuration if you wish.

Now I'll admit I'm biased. You don't have to use DI. You can use singleton. Here's a well considered article a comparing Singleton vs Dependency Injection.

I'll jump to the summery:

  1. If a dependency is ambient, meaning that it is used by many classes and/or multiple layers, use Singleton.
  2. Otherwise, inject it to the dependent classes using the Dependency Injection pattern.

Which I love because it lets me simply say this: don't write code that puts your DB in case 1.

5
  • If I want to use a Singleton, I just relabel it as a “Service Locator” that happens to have a default implementation. That is a viable (and quite widespread) dependency injection technique, though I prefer more explicit techniques like constructor injection. BTW, the GoF note the advantage that “The [singleton] pattern makes it easy to change your mind and allow more than one instance” – once you've already encapsulated the global mutable state, it becomes easier to turn it into local state.
    – amon
    Commented Dec 10, 2016 at 20:46
  • 1
    @amon Service locator is a dependency injection technique? No. No it's not. At best it lets you follow Inversion of control for everything it locates, just not itself. A dependency on the locator gets spread everywhere the need for dependencies that needed locating were located. If you're going to fill my house with garbage I guess it's better if it's one kind of garbage but I'd rather decide for myself what to put in my house. Commented Dec 10, 2016 at 21:08
  • Thank you, I hadn't realised that dependency injection is a specific term that only describes particular subset of dependency management techniques. I'm not entirely sure why you think service locators are so unconditionally more terrible than their alternatives (no IoC technique is completely transparent), but that is a discussion for another place.
    – amon
    Commented Dec 10, 2016 at 21:43
  • 1
    You're welcome. My reason is the same as Fowlers. I like it when I can look at a class and not be able to tell how it gets it's dependencies. I'd rather the class didn't know. Always be careful of what you let a class know about. Commented Dec 10, 2016 at 21:49
  • 1
    As additional argument, class-level mutable state and globally visible singletons are forms of ambient authority, whereas the dependency injection approach does not require ambient authority and thus is compatible with the object capability model. This applies to the Service Locator as well; it too can be a form of ambient authority. The aspects that make understanding security tractable in the object capability model make understanding one's code easier. Commented Dec 11, 2016 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.