Also known as the BorgIdiom.
A monostate is a "conceptual singleton" - all data members of a monostate are static, so all instances of the monostate use the same (static) data. Applications using a monostate can create any number of instances that they desire, as each instance uses the same data. What I find very nice about monostate classes is that they avoid all of the complications about having to access a particular instance of a class. Any instance is as good as another. I have found monostates do add some confusion to those who are steeped in GOF Singletons, this may be a bad thing.
I have used this technique many many times in C++, and now that I know about it, will never write a (GOF) singleton again. I would also claim that the two are isomorphic, and you could probably use a monostate.
Now, perhaps the particulars of Java or your app, or the hardware API you're wrapping will prevent this. I doubt it, but if so, that's too bad. --BramBaker? (on the XpMailingList)
Something to note: Monostates are evil in the same way that SingletonsAreEvil.
Forgive a perhaps obvious question, but how is a MonostatePattern singleton with only static data different from a regular singleton with an instance accessor? The most common use of singleton I have seen in practice is that all that want to use the singleton get a reference by calling Singleton::Instance(), then using the returned reference. The implementation of Singleton::Instance() will create the singleton if it does not exist, save the reference, and return it. If the saved reference exists, it is simply returned. The constructor for the singleton is private, so that it cannot be called outside the class, thus assuring that the only way to get a reference is through Instance(). --PeteHardie
Maybe some example code will clear things up. I'll use a "Config" object as the example, because it's probably not too terrible a use of a Singleton-like mechanism:
// Using a Singleton: Color favoriteColor = Config::getInstance()->getFavoriteColor(); SomeOtherPref pref = Config::getInstance()->getSomeOtherPref(); // ...and so on.Here is where I would use, in a standard singleton example,
Config _config = Config.Instance(); Color favoriteColor = _config.getFavoriteColor();instead. I am certainly not saying that a MonostatePattern is not valid - I am just wondering what particular benefit you see in it. --PeteHardie
// Using a Monostate: Config config; Color favoriteColor = config.getFavoriteColor(); SomeOtherPref pref = config.getSomeOtherPref(); // ...and so on. // Or, alternatively: Color favoriteColor = Config().getFavoriteColor(); SomeOtherPref pref = Config().getSomeOtherPref();The advantage here is fairly simple -- the user of the "Config" object needs to know less about the implementation of the "Config" object. This is nice in the traditional way (that is, you can vary the implementation without clients needing to know about it), but it also saves some keystrokes (and we know it's all about saving keystrokes, is it not?)
For completeness, an example implementation of the Monostate "Config" used above follows:
class Config { public: Config() { if (!initialized_) { // ...Parse the config file, registry, etc.... initialized_ = true; } } Color getFavoriteColor() const { return favoriteColor_; } SomeOtherPref getSomeOtherPref() const { return pref_; } private: static bool initialized_; static Color favoriteColor_; static SomeOtherPref pref_; }; bool Config::initialized_ = false; Color Config::favoriteColor_; SomeOtherPref Config::pref_;You dig? (Or, for that matter, do I dig?)
Instead of stealthy static data, why not just hide the singleton inside the Config constructor? Something like the following:
class Config { public: Config() : m_rep( ConfigState::getInstance() ) { } Color getFavoriteColor() const { return m_rep.getFavoriteColor(); } private: const ConfigState& m_rep; };You can also use a reference counted singleton, if you wish. Of course, if the only purpose is to get rid of typing in #getInstance, I'd probably just use a singleton instead of the Config instance constructed to use the singleton state. --RobertDiFalco
Really, I don't mind that option at all. The goal, of course, is to DoTheSimplestThingThatCouldPossiblyWork. Each of the above three structures (SingletonPattern, MonostatePattern, and your EncapsulatedSingletonPattern?), will be the simplest thing in different circumstances. They're all tools in your toolbox, but I'm betting that the MonostatePattern is the tool that will be used more than the other two -- it has the client-side simplicity of your example, but also the server-side simplicity of the original SingletonPattern.
My only problem with it is that it can create confusing code. Looking at client usage makes no indication that many instances share a single state. --RobertDiFalco
That's exactly my point -- that is an implementation detail that is not relevant to the clients. Why expose that detail on a syntactical or ideological level? I could be way off, of course.
My question related to this is, if in C++, why use a class at all? Why not: in .h:
namespace Config { Color getFavoriteColor(); };in .cpp:
namespace { class ConfigState { //make this a singleton }; } Color Config::getFavoriteColor() { return ConfigState?::Instance().color; }--ThomasMatelich?
Splitting the comment from GeorgePaci into individual arguables:
I'm not a huge fan of SingletonPattern, but I like MonostatePattern even less. One of the points of Singleton is to give you flexibility to move away from a single instance of the object, and it does do this better than a naive all-static class. Monostate seems to me to be equally (in)flexible as an all-static class, and therefore less flexible in that direction.
Actually, I think it's the exact opposite.
With a Monostate, you can just tack on the per-instantiation state as you go.
In addition, to get a reference to a Singleton, you have to use that crazy Class::getInstance() notation. With the Monostate, you can still use the basic object creation syntax.
Worse, your code will probably end up depending on all instances of the Monostate object being the same, and so when you go to add more you're screwed.
Yagni? The word "probably" is a very dangerous word when used like that. Your tests should uncover the breakage, anyway.
To top it off, I think Monostate has all the problems Singleton has (the Global Variable Temptation, mostly). --GeorgePaci
Yeah, I don't argue with that (see the very top of this page, surrounding the "SingletonsAreEvil" link.) However, it seems to me that the way Singletons enforce their singleness encourages data that would normally belong to an instance to become unnecessarily shared.
Eagerly interested in being proven wrong...
I comment not to prove you wrong, for that is as context sensitive as is the blanket statement of "Global Variable Temptation", and "Spaggetti Code" are evil. In fact it could be argued and proven that no one technigue is per se evil or a pariah of software construction. In fact use of a Singleton and Monostate can optimize code for performance, where other options are architecturally fantastic but do not provide the required qualities, as the saying goe "An infinitely flexible architecture shall take infinite time to execute". In fact, Monostate and Singleton patten can be used together to create some fundamental facilities that are far more optimal than its "touted" flexible counter part. -- Ironluca
About VbClassic (which seems to lack the static part) you could probably achieve similar functionality by using modules, as discussed in VbClassicSingleton. fs
Someone mentioned about MonoStates? in Java, it's quite simple:
class Config {
private Config(){}//this makes Config not instantiable (by anything outside this class) protected static Color color; public static Color getFavouriteColor() { return color; } public static void setFavouriteColor(Color color) { this.color=color; }}
class Main {
public static void main(String[] args) { Config.setFavouriteColor(Color.green);//this is an important bit. System.out.println(Config.getFavouriteColor());//So is this. }}
ricky_clarkson@yahoo.com
I believe the Java example above is wrong, actually. The getFavouriteColor() and setFavouriteColor() methods should not be static: the whole point of this MonostatePattern seems (to me) to be that only state needs to be or appear static. Objects and methods used to access the state can be just regular objects and methods.
So for example:
public void setFavouriteColor(Color aColor) { Config.color = aColor; }
The only problem with using the MonostatePattern in Java is that you can't declare static members in an interface and you can't, say, instantiate a different implementation for testing or based on some other runtime context.
-MichaelFortson?
I find the monostate pattern better than singleton for two main reasons. First, in a Java environment a singleton does not conform to the java beans notation, but a monostate does. This is very important in a managed environment, when objects are instantiated by a container. Secondly, you can transparently use a monostate without explicitly knowing, e.g. the client code is not tainted by the fact that a certain class implements the monostate pattern. I included below a sample implementation of a monostate in Java.
public class Monostate {
private static String data; public String getData() { return Monostate.data; } public void setData(String data) { Monostate.data = data; } static { data = "Initialization:" + Math.random(); }}
-- VasileAlaiba?
Moved from SingletonPattern
So are there any patterns for avoiding singletons then?
Check out the MonostatePattern in C++; make all the data members static. I haven't used it at work but I know a guy who swears by it -- BillWeston
If I have a bunch of these 'there should be only one of these' type objects I generally throw them on a palette or workbench that gets passed around. Instead of passing a bunch of parameters in to classes I can just pass the Palette or Workbench. This also lets folks that are maintaining the code know my intention. -- FrankMcGeough
RobertCecilMartin's comparison of SingletonPattern and MonostatePattern is available at http://www.objectmentor.com/resources/articles/SingletonAndMonostate.pdf
CategoryPattern | CategoryCreationalPatterns