Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better way than using static classes or singletons for MVVM?

Tags:

c#

mvvm

wpf

I've found that in a lot of cases, it seems (at least superficially) to make sense to use Singletons or Static classes for models in my WPF-MVVM applications. Mostly, this is because most of my models need to be accessed throughout the application. Making my models static makes for a simple way of satisfying this requirement.

And yet, I'm conflicted because everyone on the planet seems to hate singletons. So I'm wondering I there isn't a better way, or if I'm doing something obviously wrong?

like image 847
sircodesalot Avatar asked Jun 04 '13 18:06

sircodesalot


People also ask

What is the advantage of using static class over singleton class?

The advantage of using a static class is the compiler makes sure that no instance methods are accidentally added. The compiler guarantees that instances of the class cannot be created. A singleton class has a private constructor that prevents the class from being instantiated. A singleton class can have instance members while a static class cannot.

What is a singleton class in Java?

Let us discuss more about the Singleton class first. Singleton is a design pattern that makes sure that your application creates only one instance of the class anytime. It is highly efficient and very graceful. Singletons have a static property that you must access to get the object reference.

Is there a better way to use static methods and variables?

Most of the time, if you're using static methods or variables then there is almost certainly a better way. That said, there are a few instances where static methods and variables are useful. However, all of these are accessed solely by methods in the class that also contains the statics, and do not have dependencies on anything outside them.

Why can't I instantiate a class from a singleton?

Because the Singleton instance is referenced by a private static member variable, the instantiation does not occur until the class is first referenced by a call to the Instance property. This solution therefore implements a form of the lazy instantiation property, as in the Design Patterns form of Singleton.


3 Answers

There are a couple of issues with Singletons. I'll outline them below, and then propose some alternative solutions. I am not a "Never use a singleton, or you're a crap coder" kind of guy as I believe they do have their uses. But those uses are rare.

  1. Thread safety. If you have a global-static Singleton, then it has to be thread-safe because anything can access it at any time. This is additional overhead.

  2. Unit Testing is more difficult with Singletons.

  3. It's a cheap replacement for global variables (I mean, that's what a singleton is at the end of the day, although it may have methods and other fancy things).

See, it's not that Singleton's are "horrid abominations" per-se, but that it's the first design pattern many new programmers get to deal with and its' convenience obfuscates its' pitfalls (Just stick some gears on it and call it steam-punk).

In your case, you're referring to Models and these are always "instances" as they naturally reflect the data. Perhaps you are worried about the cost of obtaining these instances. Believe me, they should be negligible (down to data-access design, obviously).

So, alternatives? Pass the Model to the places that require it. This makes unit testing easier, and allows you to swap out the fundamentals of that model in a heart-beat. This also means you might want to have a look at interfaces - these denote a contract. You can then create concrete objects that implement these interfaces and voila - you're code is easily unit-testable, and modifiable.

In the singleton world, a single change to that singleton could fundamentally break everything in the code-base. Not a good thing.

like image 89
Moo-Juice Avatar answered Sep 22 '22 01:09

Moo-Juice


I think the accepted solution to this problem is to use dependency injection. With dependency injection, you can define your models as regular, non-static classes and then have an inversion of control container "inject" an instance of your model when you want it.

There is a nice tutorial at wpftutorial.net that shows how to do dependency injection in WPF: http://wpftutorial.net/ReferenceArchitecture.html

like image 39
Erik Schierboom Avatar answered Sep 20 '22 01:09

Erik Schierboom


The only static class I use is a MessageBroker because I need the same instance all through the application.

But even then it is very possible to use Unity (or another Dependency Injection/Container) to manage instances of classes that you only need one of.

This allows you to inject different versions when needed (e.g. during unit tests)

BTW: static is not the same as singleton. But I am not getting into that here. Just search stackoverflow for more fun questions on that :)

like image 35
Emond Avatar answered Sep 21 '22 01:09

Emond