should getInstance() be idempotent?

A

Andrew McDonagh

jlowery05 said:
Let's see if I got this right:

Monostate -- multiple instances, mostly shared data (can have
instance-specific data)

no...Monostate -- Multiple Instances, Shared data.

MonoState objects don't have instance data - only class data.

They are singletons...just in a different form ... you have to create
an instance of the class in order, but its internal state is always the
same as every other instance of that class.

public class MonoState {

private static String name;

public void setName(String newName){
name = newName;
}

public String getName() {
return name;
}
}


(note no constructor to initialise the name - this is preferable as it
helps show that just creating on need not also change the state of the
singleton.)

Singleton -- single instance, shared data (no instance specific data)

I would agree Monostate is generally preferrable (and I'll start using
it), but in cases where you have many members with default values,
statics just don't give you control over when initialization occurs.

As above, don't provide a constructor to initialise the class vars.
I
may not want to initialize a slew of object members if I never use them
in a particular execution path; it could be that Monostate statics
would get initialized by the JVM even if a logic path never
instantiated one.

They can be initialised to 'null' then initialised later.
 
T

Thomas Hawtin

Ed said:
I liked the quote in some article I've just read about it, "I find this
to be a delightfully twisted pattern. No matter how many instances of
MonoState you create, they all behave as though they were a single
object."

Interesting ...

I can think of different words to describe it. "Pointless", perhaps. Or
"perverse".

Prefer static creation methods over naked constructors. To use a
constructor where you don't actually mean it... lost for words.

Tom Hawtin
 
A

Alex Hunsley

Patrick said:
What about the Flyweight pattern requires the use of a Singleton
exposing a getInstance() method?

Nothing at all. But I'm interested in what your alternative method(s)
would be of ensuring re-use of existing instances that are appropriate.
You might propose a factory that returns instances (and caches
references to already created instance for possible re-use). But then
what is the essential difference between knowing that you must use
getInstance() for a singleton class and knowing that you shouldn't
create instances of an object directly, but use the factory instead?
Both require special knowledge outside of the normal constructor mechanism.
 
A

Alex Hunsley

Ed said:
Thanks, Patrick, for that reference to the MonoState pattern; I have't
seen that pattern before.

I liked the quote in some article I've just read about it, "I find this
to be a delightfully twisted pattern. No matter how many instances of
MonoState you create, they all behave as though they were a single
object."

Interesting ...

I still don't see the attraction of MonoState. It seems purposefully
wasteful - potentially loads of instances, all behaving the same, the
same state. Why bother? So you can just always call a normal constructor
and not have to worry about calling getInstance or a factory method
somewhere else? It's a trade-off, certainly.
 
A

Alex Hunsley

Thomas said:
I can think of different words to describe it. "Pointless", perhaps. Or
"perverse".

Prefer static creation methods over naked constructors. To use a
constructor where you don't actually mean it... lost for words.

I'm completely with you on this one. Being able to use a normal
constructor to construct an object that has only static members seems,
well, just silly.
I don't think the pattern name MonoState is very well chosen either - it
sounds like it means "one state", when in fact a MonoState object can
have any amount of states - but only one instance (of data), in effect.
I think the name "Singleton" is less misleading.
 
A

Alex Hunsley

Andrew said:
Flyweight is completely different to singleton/monostate

I know. What I am pointing out is that when you use a pattern like
flyweight, you are using it because you have finely grained classes and
want to use common instances of these classes in different object
compositions. MonoState would offer many different instances that share
state, which is still not ideal for flyweight - the idea of flyweight is
that the object(s) contain compositions share references to the same
object. Not to many different instances: even though those instances may
share state via MonoState, it's still wasteful...
 
A

Alex Hunsley

Alex said:
Nothing at all. But I'm interested in what your alternative method(s)
would be of ensuring re-use of existing instances that are appropriate.
You might propose a factory that returns instances (and caches
references to already created instance for possible re-use). But then
what is the essential difference between knowing that you must use
getInstance() for a singleton class and knowing that you shouldn't
create instances of an object directly, but use the factory instead?
Both require special knowledge outside of the normal constructor mechanism.

As a side note... implementing things as singleton can be a pain when it
comes to writing tests and can be limiting. Just a side issue I thought
worth mentioning.
 
J

jlowery05

I'm with you.. getInstance() might be 'funny' but it's not odd enough
to matter to most folks. Tempest in a teapot.

I'm not sure how much memory each instance of a monostate with all
static members would use, but certainly very small. But addionally, the
GC has got to track and clean all those (temporary) instances, where as
a Singleton has only one.
 
J

John C. Bollinger

Patrick said:
I agree, but would add that another problem with the
getInstance() method is that it exposes too much about the
implementation of the class. Clients of the class shouldn't care if
there is exactly one instance, one instance per thread, multiple
instances, or a clerk named Edna behind the scenes.

Oooh! I vote for Edna!
 
T

Tony Morris

jlowery05 said:
Let's see if I got this right:

Monostate -- multiple instances, mostly shared data (can have
instance-specific data)

Singleton -- single instance, shared data (no instance specific data)

I would agree Monostate is generally preferrable (and I'll start using
it), but in cases where you have many members with default values,
statics just don't give you control over when initialization occurs. I
may not want to initialize a slew of object members if I never use them
in a particular execution path; it could be that Monostate statics
would get initialized by the JVM even if a logic path never
instantiated one.

I think JVMs may be smarter about when to initialize statics nowadays,
so perhaps the point is moot.

That's what the marketing literature will tell you, but not our best
known definition of reality. Unless you can refute the many
astrophysicists before you, a singleton has never been observed to exist
- not ever - certainly not within a universe that is not known (or
otherwise) to be finite.

A singleton may exist within a context - for example, a singleton across
an object (a field), a singleton across a class loader (a static field),
a singleton across a VM, or a singleton across many VMs. Most often, I
see a singleton across a class loader, with some contrived attempt to
abstract with a method (in this example, the method is getInstance()).
To attempt to define "A Singleton" requires the bounds of that singleton
to be specified, which then goes on to suggest that it is not a
singleton after all. You have a very clear, distinct and direct
contradiction in your definition. That is, I could call a for loop index
a singleton under the very same definition that the aforementioned
marketing literature provides (and obscures ala marketing) and remain
legitimate. Isn't it wonderful how easily a mass can be so easily
misdirected by flashing lights?

To suggest that you have a "singleton" without defining the context,
assumes "a singleton across the entire universe", which is an extremely
bold claim, and certainly not something you (I am not addressing a
divine force here) or I have ever encountered.

The moral of the story is, Think For Yourself.
 
P

Patrick May

Alex Hunsley said:
Nothing at all. But I'm interested in what your alternative
method(s) would be of ensuring re-use of existing instances that are
appropriate.

I would use a Singleton, but I wouldn't expose that design
decision to users of the class. That means that the interface would
not expose a getInstance() method. The implementation of the class
might look like a MonoState or it might use the envelope-letter
technique. Clients would simply instantiate an instance of the class.

The important point is that the code of clients of the class is
not littered with getInstance() calls -- the Singleton is used like
any other class. This not only keeps the code cleaner, it decouples
the clients from the Singleton so that it could be changed to a
ThreadSingleton or even a non-Singleton in the future with no impact
to existing clients.

Regards,

Patrick
 
P

Patrick May

Alex Hunsley said:
I still don't see the attraction of MonoState. It seems purposefully
wasteful - potentially loads of instances, all behaving the same,
the same state.

The way I've typically used it, there is only one static member
variable, just as in the Singleton pattern. The number of
simultaneous instances isn't usually high and the overhead compared to
an object reference to a Singleton isn't necessarily huge.
Why bother? So you can just always call a normal constructor and not
have to worry about calling getInstance or a factory method
somewhere else? It's a trade-off, certainly.

The big benefit is that it doesn't expose your implementation
decisions unnecessarily. That makes future change easier and less
intrusive.

Regards,

Patrick
 
P

Patrick May

Alex Hunsley said:
I know. What I am pointing out is that when you use a pattern like
flyweight, you are using it because you have finely grained classes
and want to use common instances of these classes in different
object compositions. MonoState would offer many different instances
that share state, which is still not ideal for flyweight - the idea
of flyweight is that the object(s) contain compositions share
references to the same object. Not to many different instances: even
though those instances may share state via MonoState, it's still
wasteful...

Singleton is certainly one way of implementing Flyweight. You
could also use a HashTable of Flyweight instances, or any of a number
of other mechanisms for sharing references to a single instance.

Flyweight may be one extreme where the classic Singleton with
getInstance() is justified. Where the number of references is not so
high, the benefits of not exposing that amount of implementation
detail outweigh the costs of a few extra objects.

Regards,

Patrick
 
P

Patrick May

John C. Bollinger said:
Oooh! I vote for Edna!

Never underestimate the capabilities of a system with Edna
sitting at the other end of a telnet session.

Regards,

Patrick
 
C

Chris Uppal

Ed said:
I liked the quote in some article I've just read about it, "I find this
to be a delightfully twisted pattern. No matter how many instances of
MonoState you create, they all behave as though they were a single
object."

A curious question relating to a recent thread: should a MonoState
instance be considered to be immutable ?

-- chris
 
A

Alex Hunsley

Patrick said:
I would use a Singleton, but I wouldn't expose that design
decision to users of the class. That means that the interface would
not expose a getInstance() method. The implementation of the class
might look like a MonoState or it might use the envelope-letter
technique. Clients would simply instantiate an instance of the class.

I thought you might be thinking about the inner-class idea. I've never
heard it called envelope-letter but now I know!
Just so I can be clear I'm thinking along the same lines, is this basic
example what you mean by the envelope-letter:


class Fooble {
private static InnerFooble instance = null;

public Fooble() {
if (instance == null) {
instance = new InnerFooble();
}
}

// delegate all methods to inner class
public void setX(int x) {
instance.setX(x);
}

public int getX() {
return instance.getX();
}

class InnerFooble {
private int x = 0;

public void setX(int x) {
this.x = x;
}

public int getX() {
return this.x;
}
}

public static void main(String[] args) {
Fooble foobleA = new Fooble();
System.out.println("foobleA has x: "+foobleA.getX());
foobleA.setX(5);
System.out.println("foobleA has x: "+foobleA.getX());
Fooble foobleB = new Fooble();
System.out.println("foobleB has x: "+foobleB.getX());
foobleB.setX(10);
System.out.println("foobleA has x: "+foobleA.getX());
}
}


The important point is that the code of clients of the class is
not littered with getInstance() calls -- the Singleton is used like
any other class. This not only keeps the code cleaner, it decouples
the clients from the Singleton so that it could be changed to a
ThreadSingleton or even a non-Singleton in the future with no impact
to existing clients.

I can see the advantages, certainly.
alex
 
C

Chris Smith

Andrew McDonagh said:
Flyweight is completely different to singleton/monostate

Wow! I couldn't have asked for a more striking demonstration of the
Dark Side of patterns. Would it have killed anyone to say, for example:

"If there should only be one logical instance of the implementation,
the class should handle that by sharing some OO model of the shared
state while still giving each client its own object to hide that
implementation detail."

"Suppose, though, that it is important to prevent creating a copy of
an object per client, in a large application, for performance
reasons."

And we'd be in a much better place, without anyone assuming some intent
in some pattern name that was never really there. Why, oh why, do
design patterns have to block the natural ability to communicate?

Step 1: Read about a design pattern.
Step 2: Understand a design pattern.
Step 3: Practice a design pattern.
Step 4: Internalize a design pattern.
Step 5: Communicate clearly without using Capitalized Name.

IME, failure in step five follows directly from a weak or incomplete
step four (or occasionally, two). Instead of continuing to actually
design, the developer attempts to compensate by carrying around a
dictionary of patterns in his/her head, and more or less applying them
wholesale. The result is a rather rigid entity that's unable to adapt
to the situation at hand. This is accompanied by (and largely caused
by) an inability to even talk about the design in language that admits
to adaptation, if there's no Capitalized Name for the adaptation.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Alex Hunsley said:
I'm completely with you on this one. Being able to use a normal
constructor to construct an object that has only static members seems,
well, just silly.

Indeed. Given the choice, I'd say that hiding whether a class is a
singleton or not should be done by always building it with static
methods. They are certainly the more general-purpose mechanism. In the
end, though, the issues probably aren't universal enough to have a right
answer.
I don't think the pattern name MonoState is very well chosen either - it
sounds like it means "one state", when in fact a MonoState object can
have any amount of states

Eh? In the sense in which OO design uses the term, no object has
multiple states... an object has state, which is sometimes used as a
singluar noun, and sometimes as a mass noun. Perhaps you mean multiple
fields? Together, those fields would constitute the object's state.
Multiple states might be discussed if you are examining how the object
changes through the lifetime of the application.

By MonoState is presumably meant that many instances share only one
state, which would be correct. Nevertheless, I am generally in
agreement that any design pattern name is silly when used as MonoState
has been used in this thread.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

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,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top