2

Here is the flyweight pattern structural diagram:

enter image description here

Here you see UnsharedConcreteFlyweight which GoF explains:

UnsharedConcreteFlyweight : Not all Flyweight subclasses need to be shared. The Flyweight interface enables sharing; it doesn't enforce it. It's common for UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the flyweight object structure (as the Row and Column classes have).

Here as much as I understand Operation takes in extrinsicState as argument, but it will not use it at all, as far as it has allState as member data.

Is it a good design? To take arguments you don't use, and if you will use, then you will have data duplication. This may even be Liskov Substitution Principle violation?

1
  • 3
    It is a good design if it effectively solves a specific computing problem you are having, laws and principles notwithstanding. – Robert Harvey Oct 12 '16 at 18:22
1

Here as much as I understand Operation takes in extrinsicState as argument, but it will not use it at all, as far as it has allState as member data.

I don't think that is the case. allState is not a replacement for extrinsicState. It is simply the unshareable state that is differentiated from the externally stored state.

In their example:

  • Glyph is the FlyweightBase, and provides operations like Draw,
  • Character is the ConcreteFlyweight,
    • the Character's intrinsicState is its character code,
  • Rows and Columns are UnsharedConcreteFlyweights
    • Row and Columns allState holds a collection of Glyphs (which can be Rows, Columnss or Characters. They aren't shared because the collections are each unique (though GOF says they could be later made to be shared).

The extrinsicState is the GlyphContext, which is the mapping between the glyphs and fonts, and since this state is external to the flyweights, it must be passed in to both concrete and unshared concerete flyweights.

The extrinsic state logically belongs in the flyweights, and has been extracted as an adornment. It must be passed to the concrete flyweight Character so that state can be recovered, and it must be passed to unshared concrete flyweights (Row and Column), in part so that they can pass it to the Characters in turn.

It is conceivable that Rows and Columns could capture a reference to the extrinsic state (the GlyphContext) and then they truly would not use their parameter. However, as they mention, with this design, clients don't have to know whether they are shareable or not. (This extra state would also be contrary to the flyweight design, as even the reference is not really necessary.)


Is it a good design? To take arguments you don't use, and if you will use, then you will have data duplication. This may even be Liskov Substitution Principle violation?

The flyweight pattern is an optimization, if you will, and, you can think of it is a refactoring of a simpler object-oriented design that is using too many objects.

The optimization works by separating intrinsic state from extrinsic state, with the assumption that the extrinsic state can be represented more efficiently than being replicated in each object, and, that now separated, the bulk of the remainder (the intrinsic state) can be shared and reused.

After the refactoring, you can now invoke all the same object-oriented methods that previously existed, but the cost is that you have to pass the extrinsic state as an additional parameter now.

As an optimization, if you don't absolutely need it you shouldn't use it just because you can. It makes the code harder to use, understand, maintain, etc..

But in computing, there are costs, and so when you need optimization, you need it!


Also note that you don't necessarily have to implement unshared concrete flyweight's, it's just that you can if you need it.

2
  • It is not clear if you agree with me that allState = intrinsic + extrinsic. – Narek Oct 13 '16 at 14:43
  • I disagree -- these are all separate parts of the state of the system. In their example, allState is the collection of references used by Rows and Columns to create hierarchical structure. Whereas intrinsicState is the character code, and extrinsicState is the mapping data structure GlyphContext. – Erik Eidt Oct 13 '16 at 16:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.