Talk:Flyweight pattern

From Wikipedia, the free encyclopedia
Jump to: navigation, search
WikiProject Java (Rated Start-class, Low-importance)
WikiProject icon This article is within the scope of WikiProject Java, a collaborative effort to improve the coverage of Java on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
Start-Class article Start  This article has been rated as Start-Class on the project's quality scale.
 Low  This article has been rated as Low-importance on the project's importance scale.
 
Note icon
This article has been automatically rated by a bot or other tool because one or more other projects use this class. Please ensure the assessment is correct before removing the |auto= parameter.
WikiProject Computer science (Rated Start-class)
WikiProject icon This article is within the scope of WikiProject Computer science, a collaborative effort to improve the coverage of Computer science related articles on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
Start-Class article Start  This article has been rated as Start-Class on the project's quality scale.
 ???  This article has not yet received a rating on the project's importance scale.
 

Bug in Java example?[edit]

Note: I just fixed the bug described below. —Preceding unsigned comment added by 74.68.108.87 (talk) 21:59, 8 April 2010 (UTC)

I believe there's an intermittent bug in the Java example. Here's the part I'm concerned about, in the create method:

        // We are unconcerned with object creation cost, we are reducing overall memory consumption
        FontData data = new FontData(pointSize, fontFace, color, effectsSet);
        if (!FLY_WEIGHT_DATA.containsKey(data)) {
            FLY_WEIGHT_DATA.put(data, new WeakReference<FontData> (data));
        }
        // return the single immutable copy with the given values
        return FLY_WEIGHT_DATA.get(data).get();

Here's the problem: Suppose you call the create method with a certain set of parameters, for the first time. The method constructs a new FontData object (call it d0), and the local variable data refers to it. So, d0 is added to FLY_WEIGHT_DATA, and the method returns d0. No problem so far.

Now imagine that the return value of create is discarded, i.e., there are no more references to d0 except for the weak references in FLY_WEIGHT_DATA. Suppose that the garbage collector has not yet run, and that you call create again, with the same parameters that gave you the original d0. The lines quoted above construct a new FontData object that equals d0, but it's not identical to d0. FLY_WEIGHT_DATA.containsKey(data) returns true because data.equals(d0) is true. Now suppose that the garbage collector kicks in after this check, but before the return statement. Now FLY_WEIGHT_DATA.get(data) will return null because the key d0 has disappeared, and so FLY_WEIGHT_DATA.get(data).get() will fail with a NullPointerException.

Another kind of failure occurs if the garbage collecture runs after get(data) but before get(). In that case, get(data) will return the desired weak reference, but then get() will return null, presumably leading to a NullPointerException somewhere down the road.

By the way, the documentation of WeakHashMap warns of exactly this kind of problem (see the paragraph on checking for equality with ==, as well as the paragraph after that). —Preceding unsigned comment added by 74.68.108.87 (talk) 15:58, 4 March 2010 (UTC)


comment[edit]

Flyweight is a software design pattern.

The sentence above is how the articles title "builder pattern", "adapter pattern", etc. should begin. Someone who is ignorant of computer software looking at those articles should be told right at the beginning that that is what the article is about. -- Mike Hardy


Chnged the method printAtPosition() to a static one as the point of a flyweight object was to save memory. -- Jari Mustonen


each GraphicChar takes 10 bytes of heap space (8 overhead + 2 char + 4 string pointer for font)

8 + 2 + 4 = 14, not 10 --195.6.224.137 15:17, 18 October 2006 (UTC)

I'm removing the two paragraphs that start "Often the desire to use a flyweight pattern indicates another design problem" because they seem way off-topic, they contain errors (see comment above regarding addition error), and they sound a lot like original research. CMosher01 17:16, 24 October 2006 (UTC)

As the author said that this is structural pattern, According to me its not structural or object oriented pattern, it's a hybrid pattern which consist both kind of pattern.--- Sanket Patel

Thread safety issue[edit]

The article should outline the importance of being thread-safe when the Flyweight is static. The Java example should also be thread-safe, some one who doesnt know this pattern may fall in this trap. —Preceding unsigned comment added by 81.252.131.1 (talk) 09:11, 15 April 2009 (UTC)

Memory issue in the Java example[edit]

The Java example adds WeakReferences into the flyweightData map but at no point removes them. This could in time lead to a very large map, whose values would mostly end up being null-valued WeakReferences.

Actually it doesn't because the map used is a WeakHashMap and the keys are the same as the referenced value. This approach works nicely when object creation cost is low and the object itself can be used as the key.

When object creation is high and needs to be avoided as well as keeping memory usage down some sort of other key needs to be used. If the object's hashCode can be replicated with the same parameters given in the constructor then the hashCode is a good choice. But now you definitely have the problem of the map potentially growing large with null-valued WeakReferences. The solution is to attach a ReferenceQueue that removes the entry from the map.

org.apache.commons.collections.map.ReferenceMap provides a basic solution for this, but there exists a superior solution, also open sourced, here http://sesat.no/projects/sesat-commons/commons-reference-map/

> This implementation improves over org.apache.commons.collections.map.ReferenceMap > in that the synchronisation and concurrency is determined through delegation to the > map supplied in the constructor as described above.

Michaelsembwever (talk) 21:48, 20 March 2008 (UTC)

VB.Net example: Is this a flyweight?[edit]

I removed this section from the article:

VB.NET[edit]

' The "PersonFlyweight" is a "Person" stripped of all fields (to save memory) that 
' are not used in the immediate task at hand.  This is appropriate when loading millions of 
' objects into memory at once.
Class PersonFlyweight
   Public Sub New(p As Person)
      Me.FirstName = p.FirstName
      Me.LastName = p.LastName
   End Sub
 
   Public FirstName As String
   Public LastName As String
End Class
 
 
' "Person" entity with many fields.
Class Person
   Public FirstName As String
   Public LastName
   Public Address As String
   Public PreviousAddress As String
   Public PhoneNumberHome As String
   Public PhoneNumberWork As String
   Public PhoneNumberCell As String
   Public PhoneNumberFax As String
   Public Height As Double
   Public Weight As Double
End Class

To me it doesn't look like a Flyweight. It may be a pattern to save memory, but to me it doesn't look anything like the Flyweight pattern. Am I wrong? --Teglsbo (talk) 12:50, 21 April 2008 (UTC)

That is the use of a proxy pattern. The Flyweight pattern is there to prevent needing a cartesian product number of classes, not to prevent accessing a huge class. Loek Bergman (talk) 10:56, 27 June 2009 (UTC)

Illustration[edit]

The illustration seems to illustrate an object pool, not a flyweight setup. While object pools can be handy when dealing with flyeights, it isn't directly relevant to the design pattern. The illustration outright fails at communicating the concept correctly.--Henke37 (talk) 19:07, 8 July 2012 (UTC)

Python __slots__ example[edit]

The construct '__slots__' in Python does not, as the article states, 'automatically enable the Flyweight pattern for that class.' It simply removes the backing dictionary ('__dict__') in favor of a tuple. As the definition of Flyweight states at the beginning of the article, the requirement for this pattern is 'sharing as much data as possible with other similar objects.' Two slotted Python classes initialized to the same value will be different objects. 'arr=[foo(1) for i in range(1000)]' will contain 1000 different objects, not 1000 references to the same object. NO PYTHON OBJECT IS IMMUTABLE. For this reason, I don't believe this Python example is valid and should be removed. — Preceding unsigned comment added by 207.10.138.156 (talk) 22:38, 24 November 2013 (UTC)