From: Robert Klemme on
On 25.07.2010 16:39, Lew wrote:
> Magnus Warker a écrit :
>
> Don't top-post!
>
>>> It's the readibility of the code.
>>>
>>> With constant classes I can write something like this:
>>>
>>> public void setColor (Color color)
>>> {
>>> if (color == Color.WHITE)
>
> No. That would be a bug. You'd write 'if ( color.equals( Color.WHITE ) )'.

That depends on the rest of Color's class definition (whether there are
public constructors, whether the class is serializable and whether
custom deserialization is in place - all stuff someone who makes this an
enum does not have to take care of manually btw). For enums (whether as
language construct or properly implemented although this is a bad idea
since Java 5 IMHO) I would rather use "==" here because it is more
efficient and stands out visually.

> Since enums are classes, they can contain behavior. That means you won't
> need if-chains nor case constructs to select behavior; just invoke the
> method directly from the enum constant itself and voilà!

One can even have custom code *per enum value* which makes implementing
state patterns a breeze. See

http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

Kind regards

robert


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

From: Lew on
On Jul 28, 10:45 am, Robert Klemme <shortcut...(a)googlemail.com> wrote:
> On 25.07.2010 16:39, Lew wrote:
>
> > Magnus Warker a écrit :
>
> > Don't top-post!
>
> >>> It's the readibility of the code.
>
> >>> With constant classes I can write something like this:
>
> >>> public void setColor (Color color)
> >>> {
> >>> if (color == Color.WHITE)
>
> > No. That would be a bug. You'd write 'if ( color.equals( Color.WHITE ) )'.
>
> That depends on the rest of Color's class definition (whether there are
> public constructors, whether the class is serializable and whether
> custom deserialization is in place - all stuff someone who makes this an
> enum does not have to take care of manually btw).  For enums (whether as
> language construct or properly implemented although this is a bad idea
> since Java 5 IMHO) I would rather use "==" here because it is more
> efficient and stands out visually.
>

Yeah, I was corrected on that some time upthread and already
acknowledged the error. I had it in my head that we were dicussing
String contants rather than final instances of the 'Color' class.

As for using == for enums, that is guaranteed to work by the language
and is best practice.

As for writing type-safe enumeration classes that are not enums,
there's nothing wrong with that if you are in one of those corner use
cases where Java features don't quite give you what you want. The
only one I can think of is inheritance from an enumeration. However,
I agree with you in 99.44% of cases - it's almost always bad to extend
an enumeration and Java enums pretty much always do enough to get the
job done. So when one is tempted to write a type-safe enumeration
class that is not an enum, one is almost certainly making a design
mistake and an implementation faux-pas.

> One can even have custom code *per enum value* which makes implementing
> state patterns a breeze.

I have not so far encountered a real-life situation where a 'switch'
on an enum value is cleaner or more desirable than using enum
polymorphism. For state machines I'm more likely to use a Map (or
EnumMap) to look up a consequent state than a switch. Have any of you
all found good use cases for a 'switch' on an enum?

--
Lew
From: Robert Klemme on
On 07/28/2010 06:13 PM, Lew wrote:
> On Jul 28, 10:45 am, Robert Klemme<shortcut...(a)googlemail.com> wrote:
>> On 25.07.2010 16:39, Lew wrote:
>>
>>> Magnus Warker a écrit :
>>
>>>>> It's the readibility of the code.
>>
>>>>> With constant classes I can write something like this:
>>
>>>>> public void setColor (Color color)
>>>>> {
>>>>> if (color == Color.WHITE)
>>
>>> No. That would be a bug. You'd write 'if ( color.equals( Color.WHITE ) )'.
>>
>> That depends on the rest of Color's class definition (whether there are
>> public constructors, whether the class is serializable and whether
>> custom deserialization is in place - all stuff someone who makes this an
>> enum does not have to take care of manually btw). For enums (whether as
>> language construct or properly implemented although this is a bad idea
>> since Java 5 IMHO) I would rather use "==" here because it is more
>> efficient and stands out visually.
>
> Yeah, I was corrected on that some time upthread and already
> acknowledged the error. I had it in my head that we were dicussing
> String contants rather than final instances of the 'Color' class.

I hadn't made it through all branches of the thread. I should have read
to the end before posting. Sorry for the additional noise.

> As for using == for enums, that is guaranteed to work by the language
> and is best practice.
>
> As for writing type-safe enumeration classes that are not enums,
> there's nothing wrong with that if you are in one of those corner use
> cases where Java features don't quite give you what you want. The
> only one I can think of is inheritance from an enumeration. However,
> I agree with you in 99.44% of cases - it's almost always bad to extend
> an enumeration and Java enums pretty much always do enough to get the
> job done. So when one is tempted to write a type-safe enumeration
> class that is not an enum, one is almost certainly making a design
> mistake and an implementation faux-pas.
>
>> One can even have custom code *per enum value* which makes implementing
>> state patterns a breeze.
>
> I have not so far encountered a real-life situation where a 'switch'
> on an enum value is cleaner or more desirable than using enum
> polymorphism. For state machines I'm more likely to use a Map (or
> EnumMap) to look up a consequent state than a switch. Have any of you
> all found good use cases for a 'switch' on an enum?

Personally I cannot remember a switched usage of enum, The only reasons
to do it that come to mind right now are laziness and special
environments (e.g. where you must reduce the number of classes defined
for resource reasons, maybe Java mobile). But then again, you would
probably rather use ints instead of an enum type...

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

From: Tom Anderson on
On Tue, 27 Jul 2010, Tom McGlynn wrote:

> On Jul 26, 1:33�pm, Tom Anderson <t...(a)urchin.earth.li> wrote:
>> On Mon, 26 Jul 2010, Tom McGlynn wrote:
>>> On Jul 26, 8:01 am, Tom Anderson <t...(a)urchin.earth.li> wrote:
>>
>>>> But Joshua was talking about using instances of Color, where those
>>>> instances are singletons (well, flyweights is probably the right term
>>>> when there are several of them)
>>>
>>> I don't think flyweights is the right word. �For me flyweights are
>>> classes where part of the state is externalized for some purpose. This
>>> 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. �Rather
>>> than creating 200 million Star objects I might create a combination
>>> flyweight/singleton Star where each method call includes an index that
>>> 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 the
>> Gang of Four book
>
> Here's a bit of what the GOF has to say about flyweights. (Page 196
> 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 intrinsic
> 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 objects
> 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 properties
like width, height, vowelness, etc and methods like paintOnScreen. But
because every lowercase q behaves much the same as every other lowercase
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 that
are not stored in the Character. But also not things that intrinsically
belong in the Character anyway; rather, things inherited from enclosing
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.

It might well be that i have an over-narrow idea of what a Flyweight is.

> Getting back to my original concern, I don't think enumeration is a good
> word for the concept either. Enumerations are often used for an
> implementation of the basis set -- favored in Java by special syntax.
> However the word enumeration strongly suggests a list. In general the
> set of special values may have a non-list relationship (e.g., they could
> form a hierarchy). I like the phrase 'basis set' I used above but that
> suggests that other elements can be generated by combining the elements
> of the basis so it's not really appropriate either.

I can't think of a good word for this. Do we need one? What are some
examples of this pattern in the wild?

tom

--
If you're going to print crazy, ridiculous things, you might as well
make them extra crazy. -- Mark Rein
From: Tom Anderson on
On Wed, 28 Jul 2010, Tom McGlynn wrote:

> I'm a little intrigued by the discussion of the appropriate choices for
> the architecture for an n-body calculation by a group which likely has
> little experience if any in the field.
>
> Direct n-body calculations need to compute the distance between pairs of
> objects. The distances between nearby objects need to be calculated
> orders of magnitude more frequently than between distant objects. If
> the data can be organized such that nearby in [simulated] space stars
> tend to be nearby in memory, then cache misses may be substantially
> reduced. This can improve performance by an order of magnitude or more.
> In Java the only structure you have available that allows for managing
> this (since nearby pairs change with time) is a primitive array. Java
> gives no way, as far as I know, to manage the memory locations of
> distinct objects.

True, although it doesn't prevent cache locality - whereas the parallel
arrays approach immediately rules out locality of the coordinates of a
single star, because they'll be in different arrays. If you want locality,
you'd have to pack the values of all three coordinates into one big array,
which of course is possible.

The dual of the fact that java doesn't let you control locality is that
JVMs are free to control it. There is research going back at least ten
years now into allocation and GC strategies that improve locality. Indeed,
for some popular kinds of collectors, locality is a standard side-effect -
any moving collector where objects are moved in a depth-first traversal of
(some subgraph of) the object graph will tend to put objects shortly after
some other object that refers to them, and thus also close to objects that
are also referred to by that object. It may not help enormously for
mesh-structured object graphs, but it works pretty well for the trees that
are common in real life. If these Stars are held in an octree, for
example, we might expect decent locality.

tom

--
If you're going to print crazy, ridiculous things, you might as well
make them extra crazy. -- Mark Rein