Singleton VS Static Class

H

howachen

Which one you prefer....

1.


public class Person {

private static String name;
private static int age;

public static String getName() {
return name;
}
public static void setName(String name) {
Person.name = name;
}

public static int getAge() {
return age;
}
public static void setAge(int age) {
Person.age = age;
}



}

2.


public class Person2 {

private static Person2 person2Instance = null;

private String name;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

private Person2() {

}

public static Person2 getInstance() {

if (person2Instance == null)
person2Instance = new Person2();
return person2Instance;
}

}


3.


public class Test {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

Person.setName("peter");
Person.setAge(11);
System.out.println(Person.getName() + Person.getAge());

Person2 person2 = Person2.getInstance();
person2.setName("peter");
person2.setAge(11);
System.out.println(person2.getName() + person2.getAge());
}

}
 
T

Timo Stamm

public static Person2 getInstance() {

if (person2Instance == null)
person2Instance = new Person2();
return person2Instance;
}

This is a broken Singleton. You can end up with more than one instance
if you have more than one thread.


Timo
 
A

AndrewMcDonagh

Which one you prefer....

1.

snipped (MonoState is its correct name)

Snipped Singleton


For a good comparison see...

http://www.objectmentor.com/resources/articles/SingletonAndMonostate.pdf

Personally, I try hard never to create either. Instead I favour 'just
create one instance'


http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne


If I find I'm wanting to create a singleton/monostate, just because
there is only currently one instance required AND it would make it
easier for the calling code to get access to it, then I would actually
put the single instance within a Global Singleton container.

I.e. there is only one singleton in the system and it contains those
things that I need.

code eg...


Toolbox.getInstance().getPerson();


YMMV
 
T

Timo Stamm

AndrewMcDonagh said:
snipped (MonoState is its correct name)


Monostate would be:


public class Person {

private static String name;

public String getName() {
return Person.name;
}

...
}


(methods are not static)
 
A

AndrewMcDonagh

Timo said:
Monostate would be:


public class Person {

private static String name;

public String getName() {
return Person.name;
}

...
}


(methods are not static)

true, but as the object state is class bound, the static methods make no
difference.
 
C

Chris Smith

AndrewMcDonagh said:
true, but as the object state is class bound, the static methods make no
difference.

I'd have to say that when people say "monostate", most of the time they
are implying object semantics such that the state is shared. Static
methods would syntactically fit in Java, but that's really a language
design blunder. That is, if you used the class as:

Person p = new Person();
p.setName("Bob");

then it might reasonably called monostate, but it would also raise a
compiler warning with my current Eclipse compiler settings, because it's
abusing the language.

At this point, I am feeling the uncontrollable urge to point out that
one should not mistake the assignment of the word "monostate" with any
kind of endorsement of one design over another. Design patterns are (or
could be) useful in that they provide practice in evaluating well-
understood design decisions and understanding the effects of those
decisions on the resulting code. When one is discriminating about which
patterns are used, they can also collect wisdom from previous software
designers. They are, however, not at all useful for choosing designs
that have the largest possible number of design pattern names that may
be applied to their parts, especially if one is insufficiently picky
about patterns to use. Whether or not something is or is not a
monostate is merely a terminology dispute, and in no way relates to
whether something is a good idea or not.

In reading about a pattern, one should always ask: had anyone heard of
this technique before design patterns became a buzzword, or has it been
commonly used for some reason other than its author's promotion of it as
a design pattern? In other words, is it really the kind of elegant
solution that has tended to be invented again and again to solve a
variety of problems, as it was once claimed patterns were, or is it
instead just a clever trick that is the sole work of some author or
small group of authors. If the latter, then this is an "invented design
pattern". It is questionable to be whether invented design patterns
ought to be called patterns at all. They are, in any case, antithetical
to reasonable applications of patterns. Reasonable use of patterns
attempts to organize and learn from the wisdom of collective experience.
People had heard of factories long before design patterns, for example;
they are worth paying attention to. By constrast, invented design
patterns like monostate are more often a tribute to the cleverness of
some blogger than they are a collection of wisdom from a long history of
designs. They may or may not be a good idea, but I certainly don't want
my software design to be dominated by the influence of clever bloggers.
 
A

AndrewMcDonagh

Chris said:
I'd have to say that when people say "monostate", most of the time they


snipped -
At this point, I am feeling the uncontrollable urge to point out that
one should not mistake the assignment of the word "monostate" with any
kind of endorsement of one design over another.

snipped

and seconded!

I have an inherent distaste for either of the design patterns (which
lets face it - do nothing but make Global data seem like a good design -
even when we know it sucks)

The only time I've ever used MonoState, is when performing a series of
very small refactorings on a large code base, to remove a singleton. The
singleton was wildly used and spread out all over the place.

By making the Singleton to be both that AND a MonoState, I was able to
change...

public void doSomething() {
Singleton s = Singleton.getInstance();
...
}

into....

public void doSomething() {
Singleton s = new Singleton();
...
}

Then it was a case to change the above by pulling up the '..new
Singleton()' into the calling method..something like....

public void doSomething(Singleton s) {
...
}

Nothing has changed in the design, S is still the singleton .
But now I'm removing or changing how the singleton is retrived.

Repeat & rinse....

and eventually (after a few hours) I had successfully removed any call
to 'getInstance()' and replaced it with calls to 'new Singleton()'...
where appropriate.

Leaving a final, simple and automated refactoring of renaming the
Singleton class into something more appropriate.

By doing this in a series of small refactorings, I managed to
fundamentally change the design of the system with out having to use a
debugger or having any compile errors that lasted more than a few
seconds (e.g. typos caused errors).

Keep in mind - I had a comprehensive suite of unit tests that I
continuously ran during these refactorings to ensure I didn't break
anything.
 
E

Ed

(e-mail address removed) skrev:
Which one you prefer....
(snipped alternatives, which really negates this post without seeing
the previous, but there we are...)
To quote the great Hollywood phrase: "Prefer," is such an ugly word.
It's appreciated that you're asking for a preference, and that's fine,
but from an engineering point of view what matters is what has the
shortest distance on in the three-dimensional
quality-productivity-punctuality space. (Oh, I can see the c.d.t-lobby
loving that one.)

You've asked for a preference, however, that's what will be given.

The rules of encapsulation require that a client know as little as
possible about a service as possible; the singleton requires a service
to be especially instantiated (via getInstance()), the monostate does
not (it looks like any other instantiated object): so for me, the
monostate wins.

I will not attempt to evaluate the engineering consequences of this
choice as I was merely asked for a preference, but I certainly second
Andrew's first response concerning the comparison link, and I certainly
endorse Chris's uncontrolable urges, but then I don't quite endorse
Andrew's second response ("I have an inherent distaste for either of
the design patterns") because Uncle Bob gave what I consider the best
argument for or against global data that I've ever heard (I'm going to
paraphrase this as I don't have his original post to hand): all global
data is bad except the global data you need.

As a matter of interest to, I'm sure, no-one, and because I think there
should be more source-code shown on these newsgroups, I use one global
monostate in all my designs (where I can have the choice, which is very
seldom as I work mainly on updating legacy systems rather than
designing new ones) - never more and never less - and I don't use
singletons (although I did, before reading about monostate, though I
must admit that I've not yet seen a QPP improvement because of this
decision except in very, "Soft," engineering): the monostate I use is
always a domain-specific variation of the ConcreteRegistry referenced
here:
http://www.edmundkirwan.com/servlet/fractal/cs1/frac-cs40.html

..ed
 
F

Frank van Schie

Timo said:
This is a broken Singleton. You can end up with more than one instance
if you have more than one thread.

So I've read in a JSR-133 FAQ[1]. Can this be fixed with a static
initializer block? Like:

public class OneInstance
{
private static OneInstance thisObject;
static
{
thisObject = new OneInstance();
}

public OneInstance()
{
}
...
}

A linked resource in that FAQ mentioned this should be possible, but it
also had some info that made it seem as though they were talking of the
old memory model, not the J2SE 1.5 one.

[1]: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
 
T

Timo Stamm

Frank said:
Timo said:
This is a broken Singleton. You can end up with more than one instance
if you have more than one thread.

So I've read in a JSR-133 FAQ[1]. Can this be fixed with a static
initializer block?

It seems more natural to me to initialize the static field right away:

private static final Person2 p = new Person2()

public static Person2 getInstance() {
return p;
}


Timo
 
C

Chris Uppal

AndrewMcDonagh said:
By doing this in a series of small refactorings, I managed to
fundamentally change the design of the system with out having to use a
debugger or having any compile errors that lasted more than a few
seconds (e.g. typos caused errors).

Keep in mind - I had a comprehensive suite of unit tests that I
continuously ran during these refactorings to ensure I didn't break
anything.

Given the second paragraph, why bother with all those tiny steps in the first ?

I dislike automated refactorings.

-- chris
 
C

Chris Uppal

Which one you prefer....

Neither.

First off, it's very, very, unlikely that a class with a name like Person
should have only one instance (or act as if it had only one instance).

Secondly, I dislike collecting complicated state into a class. If there is a
coherent cluster of data in the system then it should be owned by a real
object, not attatched to a class as static data. Still, at least your version
uses explicit static methods, rather than the "monostate" pattern which has
been discussed elsewhere in this thread -- and which is a total abomination
IMO.

Thirdly, I dislike the classical version of the Singleton pattern. For too
many people the emphasis is on there only being one instance permitted, and
that is wrong IMO. The valuable thing about Singleton might better be
expressed with a name like "Distinguished Instance" -- i.e. there is one (or
maybe more than one) instance which is special in some way. Your code, then,
follows the classic pattern in that it hard-wires the dangerous (and pointless)
assumption that only one Person should ever be created. Now, if analysis of
the problem had shown the need for a special instance which should be easiliy
available to arbitrary callers (i.e. the equivalent of a global -- and there is
nothing wrong with globals if handled correctly), then the method for getting
that instance would not be the bland getInstance() but would be something
meaningful -- getGlobalLogger() or getSystemOwner() or something like that.
So, while I have nothing against my version of Singleton, the code you exhibit
not something I would like to see in a real system.

-- chris
 
D

dsjoblom

Chris said:
Neither.

First off, it's very, very, unlikely that a class with a name like Person
should have only one instance (or act as if it had only one instance).

Secondly, I dislike collecting complicated state into a class. If there is a
coherent cluster of data in the system then it should be owned by a real
object, not attatched to a class as static data. Still, at least your version
uses explicit static methods, rather than the "monostate" pattern which has
been discussed elsewhere in this thread -- and which is a total abomination
IMO.

Thirdly, I dislike the classical version of the Singleton pattern. For too
many people the emphasis is on there only being one instance permitted, and
that is wrong IMO. The valuable thing about Singleton might better be
expressed with a name like "Distinguished Instance" -- i.e. there is one (or
maybe more than one) instance which is special in some way. Your code, then,
follows the classic pattern in that it hard-wires the dangerous (and pointless)
assumption that only one Person should ever be created. Now, if analysisof
the problem had shown the need for a special instance which should be easiliy
available to arbitrary callers (i.e. the equivalent of a global -- and there is
nothing wrong with globals if handled correctly), then the method for getting
that instance would not be the bland getInstance() but would be something
meaningful -- getGlobalLogger() or getSystemOwner() or something like that.
So, while I have nothing against my version of Singleton, the code you exhibit
not something I would like to see in a real system.

I agree with everything said above. The main advantage of a Singleton
over a class with static data is that the singleton is just a(nother)
regular instance of the class. If there is later a need to create
additional instances of the class with separate state, there is no
requirement to change existing code using the original singleton. And
in practice, this situation does come up from time to time.

However, I would only use a singleton if a class has state. Sometimes
you see classes which have no state, but only a collection of utility
methods implemented as singletons. In that case, I would use a class
with static methods (although some braindead 'code improvement' tools
suggest using a singleton instead).

Regards,
Daniel Sjöblom
 
P

pranshu

If we are talking about a clustered application - both the above
implementations are not going to work. Both such implementations in
that case would be used for read-only data.

A "set" method - probably will require use of a RDBMS, or a file system
which permits locking.

The Get method is even more interesting.
If we had an object - we would be returning an instance of the object
there in case of above code. So the consumer can manipulate the value.
Not very neat is it ?
The get I would say is broken even in case of non-clustered
applications.

It might be better to keep it static and simple and save some effort -
rather than going all the way.

In the implementations I have done in the past: I have used static
blocks / classes for read only information. The read/write are managed
in the database. In case the amount of data in the database is too
large, the same can be optimized by time based caching and also by
using triggers in database to populate a very small table indicating
that the value has changed - which can be checked for all invocation of
Get methods, allowing the users to refresh from database only when
needed.
 

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

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top