singletons

Started by
40 comments, last by wild_pointer 21 years, 5 months ago
quote:Original post by wild_pointer
What are the drawbacks...

It''s basically a global object, and includes most of the drawbacks of such. Many programmers think they are creating a good design if they use a Singleton, on the basis that Singleton is a "Design Pattern", which is strange as all the good designers I know try to avoid global objects.
quote:
...and what do you recommend instead?

Rethinking your design so that it doesn''t necessitate a Singleton - this might require you to flex the design in a different direction. A Singleton should only be used when you want to enforce that a system *must* only have one of something, but it gets abused so that people use it when they only *desire* one of something.
Advertisement
quote:Original post by civguy
I''d use singleton for object factories, for example.

I wouldn''t. It sounds like an artificial limitation - as in what problems does it cause if you have more than one object factory? If you want various parts of your application to use the same object factory, then you organise your design around that. You shouldn''t use various mechanisms and design patterns to allow you to organise your design around an arbitrary rule taken from the solution domain.

Singletons Are Evil.
quote:Original post by SabreMan
Original post by civguy
I''d use singleton for object factories, for example.
===end quote===
I wouldn''t. It sounds like an artificial limitation - as in what problems does it cause if you have more than one object factory? If you want various parts of your application to use the same object factory, then you organise your design around that. You shouldn''t use various mechanisms and design patterns to allow you to organise your design around an arbitrary rule taken from the solution domain.

Singletons Are Evil.



I use an object called "Application" that acts as a dynamic global space for storing data and providing one log file. I ***want*** this object to be unique as obviously the running program is "a whole one", thus I enforce this behaviour by implementing the Singleton design pattern inside the Application Class.

I frankly don''t see the flaw in such design. But I am opened to suggestions

If I need local dynamic global space, I designed a Session class which instances can be stored inside the Application Instance.

I should release theese classes this week-end on sourceforge (I have to supplement the demo using application so that it demonstrates the use of Session object too). Then you can see more clearly (I hope) what I''ve done and give me some feedback



----
David Sporn AKA Sporniket
davidsporn, are you worried that you might forget and make two application objects by mistake?

just because you will only have one of something, doesn''t mean you have to enforce it.

although, saying that, murphy''s law says ''if there is more than one way to do something and one of those ways is catastrophic then someone will do it that way''

hmm...
quote:Original post by petewood
davidsporn, are you worried that you might forget and make two application objects by mistake?

just because you will only have one of something, doesn''t mean you have to enforce it.

although, saying that, murphy''s law says ''if there is more than one way to do something and one of those ways is catastrophic then someone will do it that way''

hmm...


I''m pretty sure I will not forget... at least during a few years.

But my intention is clearly to grant that whatever code is written, things like unintentional duplication will be detected at compilation time, so that one can detect that he tryed to use improperly the API.

Thus the enforcing.


----
David Sporn AKA Sporniket
quote:Original post by davidsporn
But my intention is clearly to grant that whatever code is written, things like unintentional duplication will be detected at compilation time, so that one can detect that he tryed to use improperly the API.

I''m also slightly suspicious your design might be suffering from what''s called the "God Class Problem". Obviously, there''s not enough information for me to tell that, but it''s worth a mention. In brief, the God Class Problem is something commonly created by programmers moving from action-oriented to object-oriented designs. Action-oriented designs are based around a centralised control mechanism, whereas OO prescribes distributing system intelligence amongst a number of different classes [1], with no one class being responsible for overall system behaviour. If you have classes in your system with names like Manager, Driver, System or such-like, it may indicate that you have a "God class". "Application" also sounds like it might be such a class but, as I say, it''s not possible to tell.

[1] my ever increasing skepticism of OO leads me to refute that such an aim is purely the preserve of OO, but still...
quote:Original post by davidsporn
But my intention is clearly to grant that whatever code is written, things like unintentional duplication will be detected at compilation time, so that one can detect that he tryed to use improperly the API.

quote:Original post by SabreMan
I''m also slightly suspicious your design might be suffering from what''s called the "God Class Problem". Obviously, there''s not enough information for me to tell that, but it''s worth a mention. In brief, the God Class Problem is something commonly created by programmers moving from action-oriented to object-oriented designs. Action-oriented designs are based around a centralised control mechanism, whereas OO prescribes distributing system intelligence amongst a number of different classes [1], with no one class being responsible for overall system behaviour. If you have classes in your system with names like Manager, Driver, System or such-like, it may indicate that you have a "God class". "Application" also sounds like it might be such a class but, as I say, it''s not possible to tell.

[1] my ever increasing skepticism of OO leads me to refute that such an aim is purely the preserve of OO, but still...


I''ll try to explain, but it seems I fall in this case (btw, it''s the first time I hear about "god class"). The goal of the Application instance is to store data and give access to a log file, and thoose data and log file must be accessible from any point of the application.

Here is a quick example of typical use :

  int main(){    Application * app_inst = Application::Instance() ;    app_inst->rLog() << "Initialisation sequence begins" << std::endl ;    app_inst->rPropertyMap()["foo"] = "Hello world" ;    app_inst->rPropertyMap()["width"] = 1024 ;    app_inst->rPropertyMap()["height"] = 768 ;    app_inst->rPropertyMap()["bpp"] = GetUserDefinedBpp() ;    app_inst->rLog() << "Initialisation sequence continues" << std::endl ;    Screen my_screen = new Screen (app_inst->rPropertyMap()["width"], app_inst->rPropertyMap()["height"], app_inst->rPropertyMap()["bpp"]) ;    app_inst->rLog() << "Initialisation sequence finished" << std::endl ;    //...do stuff...    app_inst->rLog() << "DeInitialisation sequence starts" << std::endl ;    delete my_screen ;    app_inst->rLog() << "DeInitialisation sequence finished" << std::endl ;    return 0 ;}  


Note : I designed the property map to be able to store some primitive types as well as std::string as well as object pointers from my class hierarchy.


----
David Sporn AKA Sporniket
quote:Original post by davidsporn
I''ll try to explain, but it seems I fall in this case (btw, it''s the first time I hear about "god class"). The goal of the Application instance is to store data and give access to a log file, and thoose data and log file must be accessible from any point of the application.

A log file''s a reasonable candidate for being globally accessible, but I have to wonder about your global dumping ground for data. Why? I mean, from your example, what are "width" and "height" - the screen size, right? Why does the screen size have to be globally accessible? When you play a sound do you need to know the screen size? It appears that you are carrying out the semantic equivalent of this:
class Application{public:  // everything}; 


I''ve been working on an application recently which began it''s life around 10 years ago, and it uses a similar scheme for storing supposedly global data. Unfortunately, the temptation for developers is to stuff a magic value in that area and then to pull it back out somewhere else, switching on the presence of and value of a particular field to perform some action. This means that the global data area has basically been used to evolve some bizarre protocol, and adding data into that area can often have seemingly unrelated side-effects, with no easy means of finding out what those side-effect will be. Yuck!
quote:Original post by SabreMan
what problems does it cause if you have more than one object factory?
What benefits would it give? Object factories provide functionality, not state, and stateless constructs are ideal for globalization. Two object factories of same type would behave identically (unless you use prototype factory or something special like that). I wouldn''t go passing Math-object around that provides me sin() and cos()-functions, since those are stateless, ''global'' operations. Similarly, I wouldn''t go passing around the object factory.
quote:Original post by SabreMan
A log file''s a reasonable candidate for being globally accessible, but I have to wonder about your global dumping ground for data. Why?

Well since one year or so I''ve played with DirectX tut, then Nehe tutorial, and I always ended up with an Application class storing some data that I decided "it has to be global !". Thus tuning this class I was obliged to implement a new field (btw it was *public* fields -yes you can shoot me, but at that time, good practices was not the point of my previous training, and I am sooo lazy...-)

On the other hand at work I''m a developping web sites and intranet applications and in environnement like theese (broadvision, jsp, ...), there is an Application object that can store the data that are globally accessible. There are also Session object that do the same for a user-session scope.

So I transposed this model to my API to have the same facilities.
(class Application and class Session)

quote:Original post by SabreMan
I mean, from your example, what are "width" and "height" - the screen size, right? Why does the screen size have to be globally accessible? When you play a sound do you need to know the screen size?

I thought the same after posting, the exemple was not relevant as such values can be stored and retrieved using the hypothetically class Screen.... But the exemple was to show what the class could do.

*Maybe* I would store the Screen instance instead.

Another possible use I''ve just thought about is to store localised messages.

quote:Original post by SabreMan
It appears that you are carrying out the semantic equivalent of this:
class Application{public:  // everything};  


That''s it. The point is that depending on the application, the "everything" is different. With my implementation I can go without rewrite a new dedicated Application class. This is my tribute to my Legendary Old Lazzyness (aka LOL ).


----
David Sporn AKA Sporniket

This topic is closed to new replies.

Advertisement