should getInstance() be idempotent?

J

jlowery05

Seems it should be, at least if there's state involved. What about
pooled Singletons, though? In that case I wouldn't necessarily expect
the same object to come back with every call.

Seeking opinions...
 
O

Oliver Wong

jlowery05 said:
Seems it should be, at least if there's state involved. What about
pooled Singletons, though? In that case I wouldn't necessarily expect
the same object to come back with every call.

Seeking opinions...

Question is vague:

If a method returns different (by reference), immutable and equal
objects, do you consider it to be idempotent?

e.g.

public List getEmptyList() {
return new ArrayList();
}

- Oliver
 
J

jlowery05

Equivalent instances may be sufficient if mutators on one instance
affect similar changes across all Singleton occurrences.

I think in practice, though, that would be difficult. You'd have to
implement some sort of ACID framework (like in a database) to ensure
that two processes aren't mutating the same object members
concurrently, otherwise you're never going to ensure equivalency on
subsequent calls.
 
O

Oliver Wong

jlowery05 said:
Equivalent instances may be sufficient if mutators on one instance
affect similar changes across all Singleton occurrences.

I think in practice, though, that would be difficult. You'd have to
implement some sort of ACID framework (like in a database) to ensure
that two processes aren't mutating the same object members
concurrently, otherwise you're never going to ensure equivalency on
subsequent calls.

"affect similar changes across all occurrences" would probably be
undesirable in the example of

public List getEmptyList() {
return new ArrayList();
}

because you might call a method called "getEmptyList", and then find
that it is not empty! (if another thread modified the a different instance,
but that modification is reflected across all instances of the list).

However, I'd argue that getEmptyList() is indeed idempotent if you take
the definition of "always does the same thing, no matter how many times you
call it".

- Oliver
 
N

neuneudr

Hi,

want more infos, want more infos :)

What are "pooled Singletons" ? 1 Match on Google :(

If you put an 's' to singleton, is it still a singleton?

"pooled singleton" gives 100 matches, but it's always
with a comma between "pooled" and "singleton" :(

I'm honestly asking, I'm kind of confused by the terminology.
 
N

neuneudr

I think in practice, though, that would be difficult. You'd have to
implement some sort of ACID framework (like in a database) to ensure
that two processes aren't mutating the same object members
concurrently, otherwise you're never going to ensure equivalency on
subsequent calls.

"...to ensure that two processes aren't mutating the same object
members concurrently, ..."

Like two threads ? Couldn't that problem simply be solved by
correctly using the synchronization mechanisms provided by
Java ? (not that it would solve other problems, like the "EmpyList"
example that Oliver Wong gave).
 
J

jlowery05

Synchronization on a single instance, sure. But were talking about
multiple objects, not a sing one.

Yeah, it's called a singleton, but it is possible to write a singleton
that creates more than one instance of itself... but now I'm thinking
that's more appropriately called a singleton factory.

So now I've convinced myself that getInstance() should always return
the identical object no matter how many times it's called (making it
idempotent), and if you want to manage multiple singletons, use a
singleton factory.
 
J

jlowery05

One of the benefits of using a singleton instead of a class with static
members is that it's possible to instantiate more than one singleton
(in theory).

A case where you might do this is where you have mulitple singletons
running in different contexts. for example, I can subclass a singleton
to add properties related to the context I'm running in. For one
context, getInstance() returns a base class, for the other a derive
(separate) instance. They're both singletons in that only one of each
type is created and each has its own instance data.

A more unusual case is where you have a singleton that's being hit on
by many threads at once and want to to instantiate more than one to
delegate the load. I've never done this, but it seems conceptually
similar to what is done with distributed EJB instances.

As in the case of EJB, there's overhead involved in keeping distributed
'singletons' in sync. At that point I'm not sure 'singleton' is an
appropriate term.

-----

The reason for bringing up this topic was that I came across some code
where a class' getInstance() method was returning a static instance
variable that was set in its constructor... bad code, IMO, but it got
me thinking if one should expect getInstance() to return the same
object everytime.

So my thought now is "yes, it should", and if you want to do something
schmancy with multiple singleton instances, then you should be using a
factory to dole them out and manage them.
 
T

Tony Morris

jlowery05 said:
Seems it should be, at least if there's state involved. What about
pooled Singletons, though? In that case I wouldn't necessarily expect
the same object to come back with every call.

Seeking opinions...

Better, should getInstance() exist?
Answer: no, the singleton antipattern should be avoided always since
there is always a more appropriate alternative that aligns with formal
notation of requirement specification (the limitations of Java itself
withstanding).

A singleton is only ever used for one of two things:
1) A global point of access for two unrelated components to be capable
of sharing data (spot the contradiction in this statement).
2) Someone is too lazy to provide the appropriate declaration of
abstraction to whatever contract would otherwise use a singleton (this
one is pretty obvious).

Books have agendas other than to portray truth - for example, to make
money for the author/publisher. They are not divine truth, not even GoF.
 
T

Tony Morris

jlowery05 said:
Seems it should be, at least if there's state involved. What about
pooled Singletons, though? In that case I wouldn't necessarily expect
the same object to come back with every call.

Seeking opinions...


Better, should getInstance() exist?
Answer: no, the singleton antipattern should be avoided always since
there is always a more appropriate alternative that aligns with formal
notation of requirement specification (the limitations of Java itself
withstanding).

A singleton is only ever used for one of two things:
1) A global point of access for two unrelated components to be capable
of sharing data (spot the contradiction in this statement).
2) Someone is too lazy to provide the appropriate declaration of
abstraction to whatever contract would otherwise use a singleton (this
one is pretty obvious).

Books have agendas other than to portray truth - for example, to make
money for the author/publisher. They are not divine truth, not even GoF.
 
R

Raymond DeCampo

Oliver said:
"affect similar changes across all occurrences" would probably be
undesirable in the example of

public List getEmptyList() {
return new ArrayList();
}

because you might call a method called "getEmptyList", and then find
that it is not empty! (if another thread modified the a different
instance, but that modification is reflected across all instances of the
list).

However, I'd argue that getEmptyList() is indeed idempotent if you
take the definition of "always does the same thing, no matter how many
times you call it".

But that is not the definition of idempotent. An idempotent
transformation I is one such that I^2 = I. Applied to a method, that
would mean that the second call has no effect, not that it does the same
thing as the first call. A method such as Arrays.sort() is idempotent.

Almost all (reasonable) methods will satisfy the definition the way you
have written it. E.g., a method to square a value "always does the same
thing" but is not idempotent.

I've not sure that the term idempotent applies to a method that does not
accept arguments or modify internal state. For the above getEmptyList()
method, the heap is modified in a different way for each invocation;
that may be nitpicking however.

Ray
 
A

Andrew McDonagh

Tony said:
Better, should getInstance() exist?
Answer: no, the singleton antipattern should be avoided always since
there is always a more appropriate alternative that aligns with formal
notation of requirement specification (the limitations of Java itself
withstanding).

+1
 
P

Patrick May

Tony Morris said:
Better, should getInstance() exist?
Answer: no, the singleton antipattern should be avoided always since
there is always a more appropriate alternative that aligns with
formal notation of requirement specification (the limitations of
Java itself withstanding).

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. If there should
only be one instance of the implementation of a class, the class
should handle that (with, for example, the MonoState pattern) without
exposing the details to the outside world.

Regards,

Patrick
 
A

Alex Hunsley

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. If there should
only be one instance of the implementation of a class, the class
should handle that (with, for example, the MonoState pattern) without
exposing the details to the outside world.

Suppose you're using Flyweight. What do you suggest then? MonoState
isn't great for everything.
 
A

Andrew McDonagh

Alex said:
Suppose you're using Flyweight. What do you suggest then? MonoState
isn't great for everything.

Flyweight is completely different to singleton/monostate
 
E

Ed

Patrick said:
If there should
only be one instance of the implementation of a class, the class
should handle that (with, for example, the MonoState pattern) without
exposing the details to the outside world.

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 ...

..ed
 
P

Patrick May

Alex Hunsley said:
Suppose you're using Flyweight. What do you suggest then? MonoState
isn't great for everything.

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

Regards,

Patrick
 
J

jlowery05

Idempotent, indempotent: Refers to an operation that produces the same
results no matter how many times it is performed.

Borrowed definitions in computer science tend to be looser than the
original. Basically what I was asking was if getInstance() should
return the same object on every call. Call it what you will.
 
J

jlowery05

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.
 
P

Patrick May

My main point is that even when Singleton is the best choice,
exposing that decision by requiring the use of getInstance() is not
good design.

Regards,

Patrick
 

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,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top