views:

111

answers:

4

The possible answers are either "never" or "it depends".

Personally, I would say, it depends.

Following usage would make a collection appear (to me) to be a flyweight:

public final static List<Integer> SOME_LIST = 
  Collections.unmodifiableList(
    new LinkedList<Integer>(){ // scope begins
      {
        add(1);
        add(2);
        add(3);
      }
    } // scope ends
  );

Right? You can't ever change it, because the only place where the "original" collection object is known (which could be changed), is the scope inside unmodifiableList's parameter list, which ends immediately.

Second thing is: when you retrieve an element from the list, it's an Integer which itself is a flyweight.

Other obvious cases where final static and unmodifiableList are not used, would not be considered as flyweights.

Did I miss something?
Do I have to consider some internal aspects of LinkedList which could compromise the flyweight?

+3  A: 

i think you are referring to the flyweight pattern. the fundamental idea of this pattern is that you are dealing with complex objects whose instances can be reused, and put out different representations with its methods.

to make such a object work correctly it should be immutable.

immutability is clearly given when creating a List the way you described. but since there is no external object/parameters on which the SOME_LISt operates on i would not call this an example of a flyweight pattern.

another typical property of the flyweight pattern is the "interning" of such objects. when creating just a single instance of an object this does not make sense.

if you are dealing a lot with lists that are passed around from one object to another and you want to ensure the Immutability, a better option might be to use Google-Collections.

final static ImmutableList<Integer> someList = ImmutableList.of(1, 2, 3);

of course it is also possible to construct more complex Immutable Objects with Builders.

this creates an instance of an immutable list. it will still implement the List interface, but will refuse to execute any add(),addAll() set(), remove() operation.

so you can still pass it to methods when a List interface is required, yet be sure that its content is not altered.

Andreas Petersson
+1  A: 

I think your example are for immutable objects, a flyweight is something quite different. Immutable objects are candidates for flyweight, but a flyweight doesn't have to be immutable, it just has to be designed to save memory.

Peter Lawrey
No, as far as I know, are flyweights objects which are guaranteed to be be immutable to be shareable between threads without synchronization.
ivan_ivanovich_ivanoff
...Hmmm, or I'm confusing flyweight and atomic aspects.
ivan_ivanovich_ivanoff
A: 

Integer is only a flyweight from -128 to 127.

See also http://www.javaworld.com/javaworld/jw-07-2003/jw-0725-designpatterns.html.

bwalliser
Ivan, Integer.valueOf (or equivalently boxing) guarantees that for ints -128 to 127 you get exactly the same instance back. More values might come back the same depending upon implementation and configuration.
Tom Hawtin - tackline
Ah, right! I forgot about the fact that Integers would most probable get unboxed ;)
ivan_ivanovich_ivanoff
+1  A: 

Having the library detect that the mutable List has not otherwise escaped is a bit of an ask, although theoretically possible.

If you serialise the returned object, then trusted code could view the internal object. Although the serialised form of the class are documented, it's not documented that the method uses those classes.

In practical terms, any cache is down to the user of the API.

(Why LinkedList for an immutable list, btw? Other than it changes the unmodifiable implementation.)

Tom Hawtin - tackline