Can use of singletons denote poor project design?

J

John Fly

I'm working on a large project(from scratch). The program is
essentially a data file processor, the overall view is this:

A data file is read in, validated and stored in a memory structure
similar to a database or XML representation. Rules to modify the stored
data will be executed, then the data will be transformed into an output
format.

Think something similar to FormatA -> XML -> Manipulate XML -> FormatB

The project is large but so far I have been able to keep it very
modular using OO design. I do however have questions about my use of
singletons for certain aspects of the program.

*
I've found the use of singleton objects quite nice for various aspects
of this program, I do enjoy having the ability to use a singleton class
by using the Class::Instance() syntax, thus removing the need to pass
instances around in all my function calls. Also very useful is the
ability to use a guarenteed single instance by simply including the
header containing my singleton.


Right now I use them for :

Logging server : A central message storage and distribution to N number
of reports/logs)
Program State : Again a central point to keep track of program status.
Central Data representation


I didn't know if the use of multiple singletons could represent a
design flaw and would like some opinions on their use or the use of
multiple singletons in a single project.

I know its vague, but without going into a verbose write-up I don't
know what else might be of value here. If there is a bit of
information I can provide, just ask.

Thank you,
JF
 
P

Phlip

[X-posted to comp.object and followups set]

John said:
I've found the use of singleton objects quite nice for various aspects
of this program, I do enjoy having the ability to use a singleton class
by using the Class::Instance() syntax, thus removing the need to pass
instances around in all my function calls. Also very useful is the
ability to use a guarenteed single instance by simply including the
header containing my singleton.

The most important design feature is testability. Classes must rigorously
decouple from each other to submit to test cases with very fine
granularity.

(You do _have_ test cases, don't you?)
Right now I use them for :

Logging server : A central message storage and distribution to N number
of reports/logs)
Program State : Again a central point to keep track of program status.
Central Data representation

To pass fake data into the modules that use those systems, would you push
the fake data into the singleton, and let the modules use it?

That situation could be improved. In general, if the reason to declare a
Singleton is "because there's only one of them", then test cases always
violate this prerequisite because there's always many of them!
 
J

Jay_Nabonne

On Fri, 24 Feb 2006 11:17:18 -0800, John Fly wrote:

Right now I use them for :

Logging server : A central message storage and distribution to N number
of reports/logs)
Program State : Again a central point to keep track of program status.
Central Data representation


I didn't know if the use of multiple singletons could represent a
design flaw and would like some opinions on their use or the use of
multiple singletons in a single project.

The answer, as always, is "it depends". But since you mentioned logging,
you may want to look at "aspect-oriented programming". One site is:

http://www.aspectprogramming.com/aop.html

- Jay
 
D

Daniel T.

"John Fly said:
I'm working on a large project(from scratch). The program is
essentially a data file processor, the overall view is this:

A data file is read in, validated and stored in a memory structure
similar to a database or XML representation. Rules to modify the stored
data will be executed, then the data will be transformed into an output
format.

Think something similar to FormatA -> XML -> Manipulate XML -> FormatB

The project is large but so far I have been able to keep it very
modular using OO design. I do however have questions about my use of
singletons for certain aspects of the program.

*
I've found the use of singleton objects quite nice for various aspects
of this program, I do enjoy having the ability to use a singleton class
by using the Class::Instance() syntax, thus removing the need to pass
instances around in all my function calls. Also very useful is the
ability to use a guarenteed single instance by simply including the
header containing my singleton.


Right now I use them for :

Logging server : A central message storage and distribution to N number
of reports/logs)
Program State : Again a central point to keep track of program status.
Central Data representation


I didn't know if the use of multiple singletons could represent a
design flaw and would like some opinions on their use or the use of
multiple singletons in a single project.

I know its vague, but without going into a verbose write-up I don't
know what else might be of value here. If there is a bit of
information I can provide, just ask.


Ask this on comp.object.
 
G

gottlobfrege

Re: Can use of singletons denote poor project design?

I can answer the subject without reading the rest:

Yes. The use (ie *overuse*) of any pattern can denote poor project
design.

more comments within...

John said:
I'm working on a large project(from scratch). The program is
essentially a data file processor, the overall view is this:
Think something similar to FormatA -> XML -> Manipulate XML -> FormatB
*
I've found the use of singleton objects quite nice for various aspects
of this program, I do enjoy having the ability to use a singleton class
by using the Class::Instance() syntax, thus removing the need to pass
instances around in all my function calls.

I don't want to be a jerk, and it is hard to convey subtleties in
email, but I think it may be useful to you if I point out your above
statement, and in particular, if I magnify an aspect of it in an
*overly* bluntly way:

it sounds like you enjoy global variables, because you are lazy.

I doubt you are lazy, (in fact it sounds like your are making extra
effort to use OOP, code separation, etc) but I point out how that
sentence sounds, as something to reflect upon. In fact, if I didn't
think you cared, I wouldn't bother pointing it out.
Also very useful is the
ability to use a guarenteed single instance by simply including the
header containing my singleton.


Right now I use them for :

Logging server : A central message storage and distribution to N number
of reports/logs)
Program State : Again a central point to keep track of program status.
Central Data representation

If by central data representation you mean the 'XML', then yeah, that
should NOT be a singleton (IMO). Basically, I've been leaning more and
more towards the rule that nothing is a singleton. Make the class
work, then only make one of them. Even wrap the class into a
singleton, but the class should work on its own as non-singleton.
There are going to be exceptions, but that's my general rule.

In your particular case, I can imagine that you could, someday in the
future, have more than one XML 'document' being processed at a time, so
it shouldn't be a singleton.

Another, maybe better way to say it, is that it should only be a
singleton if singleton-ness is intrinsic to the class, not just because
of its usage in your program.

Thus, Logging server is NOT a singleton, but you probably only have one
in your program.
Program State is *maybe* a singleton, because you really can only have
ONE Program State in a program (the program can only be in one state at
a time). But hey, what if you wanted to save/restore states? etc...
Depends what 'Program State' really means, actually. - Is it just a
place you put all your globals???
 
J

John Fly

Thank you for all the good replies.


To Phlip
The most important design feature is testability. Classes must rigorously
decouple from each other to submit to test cases with very fine
granularity.

(You do _have_ test cases, don't you?)

Yes, I agree. I usually develop my pieces in seperate projects,
test and then combine with another piece, test again. -wash, rinse,
repeat- until they are all hooked up together.

This is one reason I enjoy using the singleton, I don't have to expect
certain objects being passed around in functions and classes when I
don't need them.

Example: Part of this large program parses and validates the input. I
can either hook this into this large data translation project, or just
use is "standalone" as a data file validation program.

When used as a standalone piece I do not need to hook into either the
data storage classes, nor the output side. Using a singleton allows me
to facilitate this with the simple inclusion or omission of a header
file.

To Daniel T.
Ask this on comp.object

While my question relates to program designin general, I also want
language reasons why the pattern might be poor design indicator. Or
even have someone point out possible runtime issues that arise with
singletons.

To (e-mail address removed)
it sounds like you enjoy global variables, because you are lazy.

:) point taken. I does *sound* like a lazy approach.

I actually dislike any globle type constructs, thus the reason I post
about singletons(they are very much like a global variable).
Even wrap the class into a
singleton, but the class should work on its own as non-singleton.
There are going to be exceptions, but that's my general rule.

This is how its actually implemented in my program. Accidential
oversight on my part.

Is it just a place you put all your globals???

No globals exist besides my few singletons :)
 
P

Phlip

John said:
Yes, I agree. I usually develop my pieces in seperate projects,
test and then combine with another piece, test again. -wash, rinse,
repeat- until they are all hooked up together.

And you run all the previously passing tests after every tiny code change?
So often that you rarely need to debug?
Example: Part of this large program parses and validates the input. I
can either hook this into this large data translation project, or just
use is "standalone" as a data file validation program.

Right; the modules should be completely decoupled.
When used as a standalone piece I do not need to hook into either the
data storage classes, nor the output side. Using a singleton allows me
to facilitate this with the simple inclusion or omission of a header
file.

That's just compile-time decoupling.
To Daniel T.

While my question relates to program designin general, I also want
language reasons why the pattern might be poor design indicator. Or
even have someone point out possible runtime issues that arise with
singletons.

That's why comp.object's the better newsgroup.

Not to besmirch comp.lang.c++, but posting to the most on-topic newsgroup
will get you the best answers.
I actually dislike any globle type constructs, thus the reason I post
about singletons(they are very much like a global variable).

They enjoy most of the reasons globals are wrong. Adding syntactic sugar to
a global doesn't make it better.
No globals exist besides my few singletons :)

To achieve the moral high-ground here, you might admit that most modules do
not write on your Singletons (do not set their Set() methods). Global
constants are harmless, therefor global defacto-constants inside Singletons
are mostly harmless.
 
D

Daniel T.

"John Fly said:
I'm working on a large project(from scratch). The program is
essentially a data file processor, the overall view is this:

A data file is read in, validated and stored in a memory structure
similar to a database or XML representation. Rules to modify the stored
data will be executed, then the data will be transformed into an output
format.

Think something similar to FormatA -> XML -> Manipulate XML -> FormatB

The project is large but so far I have been able to keep it very
modular using OO design. I do however have questions about my use of
singletons for certain aspects of the program.

*
I've found the use of singleton objects quite nice for various aspects
of this program, I do enjoy having the ability to use a singleton class
by using the Class::Instance() syntax, thus removing the need to pass
instances around in all my function calls. Also very useful is the
ability to use a guarenteed single instance by simply including the
header containing my singleton.


Right now I use them for :

Logging server : A central message storage and distribution to N number
of reports/logs)
Program State : Again a central point to keep track of program status.
Central Data representation


I didn't know if the use of multiple singletons could represent a
design flaw and would like some opinions on their use or the use of
multiple singletons in a single project.

I know its vague, but without going into a verbose write-up I don't
know what else might be of value here. If there is a bit of
information I can provide, just ask.

Again I find myself following Phlip, if he wants to dive in face
first... :)

Yes John, Signletons *can* denote poor project design, but they don't
always do so. I doubt a project would ever be called ill-designed simply
because no singletons existed in it however, so you are right to be
concerned. The real question in *this* case though is, "Do the
singletons in my program denote poor project design?" I don't know the
answer to that question, but I will give you an example of a singleton
that I feel *might* denote poor design and let's see what happens...

At the Microsoft website <http://tinyurl.com/30wa>, is an example of a
singleton used to explain the concept:

For example, when a class is being used to maintain an incremental
counter, the simple counter class needs to keep track of an integer
value that is being used in multiple areas of an application. The
class needs to be able to increment this counter as well as return
the current value. For this situation, the desired class behavior
would be to have exactly one instance of a class that maintains the
integer and nothing more.

Sounds quite harmless doesn't it? A perfect example of a singleton?

The problem comes in when several different modules in our program start
incrementing the counter, reading its current value, and performing
different behaviors based on its value. Module A increments the counter,
Module B detects that the counter is over a certain threshold and does
something as a result. IE module A indirectly caused module B to change
state. A and B are coupled together (A uses B) without there being any
explicit or obvious mechanism, and we can't test this interaction
without bringing both modules and the singleton into the test harness.

Now think about the same problem, but there are 5 or 25 different
modules that all increment that counter, and perform operations based on
its state. That's some nasty coupling there.

You see, a singleton in and of itself isn't "bad design" (even this
counter class,) it all depends on how it's being used. If the state of
the singleton causes other modules to change their behavior, *then* it's
bad design.

In your particular situation, I suspect the logging_server is a fine
example of the singleton pattern, I doubt that there are any modules
that change state or behavior based on the state of the logging_server.

However, I'm not so sure about your Program State singleton. I suspect
that its state *does* affect many different modules in a non-obvious and
non-local way, but I could be wrong, I'm just going by your short
description of the thing and its name.

To Phlip and Daniel Parker... One of you is saying, "sometimes
singletons are bad" the other is saying, "they're not always bad." Let
me say, "your both right." :)
 
D

Dietmar Kuehl

John said:
Right now I use them for :

with "them" meaning singletons.
Logging server : A central message storage and distribution to N number
of reports/logs)
Program State : Again a central point to keep track of program status.
Central Data representation


I didn't know if the use of multiple singletons could represent a
design flaw and would like some opinions on their use or the use of
multiple singletons in a single project.

The use of multiple singletons does not represent a design flaw. However,
using singletons as glorified global data does! A singleton reasonably
represents a unique resource. A central messaging service fits this
description: there is only one and there cannot be more than one. Keeping
track of program status is, however, bad design: a good litmus test for
inappropriate use of a singleton is imagining a multi-threaded program
performing the same task in parallel. Will it work with the use of the
singleton? The central logging facility stays just what it was: the,
well, central logging facility. The program state, however, becomes each
thread's state and it won't work with just a single singleton.
 
J

John Fly

I believe some of the contentious points here have come about because
of the reason posted earlier by (e-mail address removed)
I doubt you are lazy, (in fact it sounds like your are making extra
effort to use OOP, code separation, etc) but I point out how that
sentence sounds, as something to reflect upon. In fact, if I didn't
think you cared, I wouldn't bother pointing it out.

After reading all the replies and links I seem to fit all the proper
uses of singletons as described(mostly), but I feel I didn't put that
information out very well.

I do have one question for Philip:
To achieve the moral high-ground here, you might admit that most modules do
not write on your Singletons (do not set their Set() methods). Global
constants are harmless, therefor global defacto-constants inside Singletons
are mostly harmless.

Forgive me if I mis-understand, right now the opposite is true, evey
module does or can call "set" methods on the singleton(s).

reflecting on the comment on multithreading from dietmar and Philip's
comments have made me realize that I need to go back and refactor much
of the information I was keeping in the "program state" part of the
data format class structure. BTW this was already in my head because
no real design time was given, and I've really been the sole developer.
This just gave me the added push I need to get the cogs in my mind
moving properly.

I have some work ahead of me, but I'll be back with a better design and
more questions later.

Thank you all
JF




Hope none of my replies were too terse or sounded arguementative, its
been a long day at the end of an even longer week.
 
P

Phlip

John said:
Forgive me if I mis-understand, right now the opposite is true, evey
module does or can call "set" methods on the singleton(s).

Hmm. Suppose the Foo module Sets a 42 into a Singleton. Then the Bar module
reads it and uses the 42.

Now change the program. Maybe change Frob that calls Foo and Bob that calls
Bar. You don't notice that Bar now runs before Foo.

The program will fail in a mysterious way, at runtime.

If Bar called Foo directly to get the 42, then more kinds of changes to the
code will either work or fail at compile time.
reflecting on the comment on multithreading from dietmar and Philip's
comments have made me realize that I need to go back and refactor much
of the information I was keeping in the "program state" part of the
data format class structure. BTW this was already in my head because
no real design time was given, and I've really been the sole developer.
This just gave me the added push I need to get the cogs in my mind
moving properly.

Please don't say "refactor" without unit tests. That word is spreading a
little too far. I'm aware it appears in the test-free book Design Patterns,
but the book Refactoring has since taken care of that.
I have some work ahead of me, but I'll be back with a better design and
more questions later.

Please put them on . The people on this newsgroup who like
only raw sterile C++ syntax questions are getting antsy. And people using
other languages deserve to read these threads.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top