Re: Class Constants - pros and cons
On Jul 29, 10:39 am, Alan Gutierrez <a...@blogometer.com> wrote:
Tom McGlynn wrote:
On Jul 29, 7:20 am, Tom Anderson <t...@urchin.earth.li> wrote:
On Tue, 27 Jul 2010, Tom McGlynn wrote:
On Jul 26, 1:33 pm, Tom Anderson <t...@urchin.earth.li> wrote:
On Mon, 26 Jul 2010, Tom McGlynn wrote:
On Jul 26, 8:01 am, Tom Anderson <t...@urchin.earth.li> wrote:
But Joshua was talking about using instances of Color, where those
instances are singletons (well, flyweights is probably the right t=
erm
when there are several of them)
I don't think flyweights is the right word. For me flyweights ar=
e
classes where part of the state is externalized for some purpose. T=
his
is orthogonal to the concept of singletons. E.g., suppose I were
running a simulation of galaxy mergers of two 100-million-star
galaxies. Stars differ only in position, velocity and mass. R=
ather
than creating 200 million Star objects I might create a combination
flyweight/singleton Star where each method call includes an index t=
hat
is used to find the mutable state in a few external arrays.
I am 90% sure that is absolutely not how 'flyweight' is defined in t=
he
Gang of Four book
Here's a bit of what the GOF has to say about flyweights. (Page 19=
6
in my version)....
"A flyweight is a shared object that can be used in multiple contexts
simultaneously. The flyweight acts as an independent object in each
context--it's indistinguishable from an instance of the object that's
not shared.... The key concept here is the distinction between intrin=
sic
and extrinsic state. Intrinsic state is stored in the flyweight. =
It
consists of information that's independent of the flyweight's context=
,
thereby making it shareable. Extrinsic state depends on and varies=
with
the flyweights context and therefore can't be shared. Client objec=
ts
are responsible for passing extrinsic state to the flyweight when it
needs it."
That's reasonably close to what I had in mind.
Yes, point taken. I'm still not happy with your usage, though.
IIRC, the example in GoF is of a Character class in a word processor. =
So,
a block of text is a sequence of Character objects. Each has propertie=
s
like width, height, vowelness, etc and methods like paintOnScreen. But
because every lowercase q behaves much the same as every other lowerca=
se
q, rather than having a separate instance for every letter in the text=
, we
have one for every distinct letter.
The extrinsic state in this example is the position in the text, the
typeface, the style applied to the paragraph, etc. Certainly, things t=
hat
are not stored in the Character. But also not things that intrinsicall=
y
belong in the Character anyway; rather, things inherited from enclosin=
g
objects.
Whereas in your case, the array offset *is* something intrinsic to the
Star. If it had been something else, say the coordinates of the centre=
of
mass of the local cluster, then i'd agree that that was Flyweightish. =
But
i'm not so sure about the array index.
Hmmm.... The GOF has the location of the letter as extrinsic state,
while I'm suggesting the location of the star. Seems pretty
comparable. My use of the
array index is simply the way I supply the extrinsic information, it's
not intrinsic to a given Star [and in fact the index of the same
'Star' might change during the simulation, since the array is likely
to be resorted continually in the process]. I wonder if the stickin=
g
point is the lack of any internal state. But the GOF notes that the
FlyWeight is particularly applicable when "Most object state can be
made extrinsic". This doesn't mean that Star isn't a real class. =
We
can have lots of methods in the Star class, e.g.,
distanceFromNeighbor(i), move(), accelerate(), force(), ...
I don't think the state of the `Star` can be extract from the `Star`.
The idea behind the Word Processor example is that you can cache the
font size in an object along with the character code itself, and have an
object that can be reused and reset into the document at any location,
and then participate in a `Composite` pattern, where the characters
participate as tiny graphical objects.
But this implies that 11pt Helvetica 'C' is one object that is reused.
I'm assuming that each of these `Star` objects will have different vales
entirely, therefore `Flyweight` does not apply much at all.
I've called this a tiny `Adaptor` because you're going to take a
`MappedByteBuffer` or parallel arrays of primitives, or something
structure that stores the state of the object, and when you need an
object, create a temporary wrapper around the state of a `Star` stored
at a particular index.
By the GOF's definition an Adapter is used to convert one interface to
another. So given what I would call a FlyWeight style interface
interface IndexedStar {
double[] getPosition(i)
}
then if you want to have a
interface NonIndexedStar {
double[] getPosition()
}
you could create an adapter class
class StarAdapter {
int index;
IndexedStar base;
StarAdapter(int i, IndexedStar star} {
index = i;
this.base = star;
}
double[] getPosition() {
return base.getPosition(i);
}
}
[I'm not suggesting this is a good way to go, just trying
to clarify what the terms mean to me.]
Why is the position of a star any more 'intrinsic' to the star, than
the position of a character is to the character? I think the
difference in perception comes from the fact that as this toy problem
has been set up, there is no internal state for the star. Suppose we
make the problem a little more complex. We have 25 classes of star:
5 ages x 5 spectral types with 4,000,000 of each. Now there are 25
flyweight instances which have different masses, temperatures,
brightness, color, metallicity, magnetic fields, whatever... If I
want to generate an image of the simulation at some time, I need to
use the internal state of the flyweights to generate the image just as
we need the actual patterns of each glyph to generate a page of text.
If this isn't a flyweight what's missing? If it is, note that I
could be using an identical mechanisms to store the position/
velocity... as before.
So I think the issue is that people are unfamiliar with FlyWeights
with little internal state but perhaps I'm missing some more essential
difference.
Maybe this goes back to your thoughts on this being an adapter, which
I'll recast in a positive way: Use of a no-internal state flyweight
can be used to as an adapter to give an object oriented interface for
elements of arrays or other structures.
Regards,
Tom McGlynn