What is Flyweight pattern?

Researching a bit to better understand the logic that leads strings in Java to be immutable , I found that "Internation" of strings is an example of the pattern Flyweight.

According to the Wikipedia article this pattern can be used to reduce memory consumption, but it was not very clear to me what this Pattern does and how it is implemented. Would the default be a kind of cache of values?

What is the Flyweight pattern ? When should we use it and what would be good examples of using this technique besides string interning?

Author: Anthony Accioly, 2016-11-11

1 answers

Memory saving

It is a form of cache yes, but it is more for sharing.

Is always useful when you need to have multiple instances of an object that have basically the same value. This obviously makes more sense when these objects are relatively large or when there is a large amount sharing of them.

It is clear that the cache (by Memoization or something similar) usually tries to avoid that a processing has already occurred has to occur again. Memory savings can occur, but the opposite can also occur, e.g., keeping things in memory that are not even used.

The Flyweight is more intended to save memory.

Performance

In some rarer cases, depending on the implementation, it is also possible to use memory for something that is not needed.

There may be a gain in processing because not so many are created objects, but nothing expressive. The economy occurs in creation and not in use, which tends to exist in greater proportion than creation.

There may even be some loss creating something unnecessary.

And there may be gain by optimizing memory usage and avoiding garbage collections, swap and loss of reference locality.

Almost a Singleton

It reminds a little of the Singleton, but it doesn't need to have a single instance, it can have several objects if they are different. The Singleton has an object of a certain type that is shared by every application. The Flyweight has as many objects as you need, but each identical object - same type and same value - is shared.

So we can say that it is useful also to maintain a canonical form of the object.

Immutability and identity

Note that the string interning has limitations, it occurs only in objects defined at compile time. Two identical strings created at runtime will not be internalized, at least not automatically (see String.intern() e string.Intern()).

Just like the strings, any of these objects are usually immutable, because if something changes in them, they become another identity. Having other internal values, it is another object; that changed object can no longer be shared with the others who kept their values.

There are many cases where part of the object can be shared and part needs something custom. Then a mechanism can be used to join the two things together. They talk a lot in shared State ( intrinsic ) and non-shared State (extrinsic). If there was no such separation some objects would always have a different identity and could not be shared.

Interestingly this is one more of the patterns that disassemble a bit the OOP way of doing things, at least in some specific scenarios. Instead of inheritance, composition is used. The inheritance would possibly have an inherited part that does not change on all objects, with the composition of the Flyweight that part can be shared.

Like much of the design standards, it is often used in conjunction with other standards.

Examples

Games

It is widely used in games. I don't know if they used it, but think of the Age of Empires that can have 200 battle units per Civilization. On old computers it would slow down. Already the Cossacks , which allows 32 thousand units, even on old computers ran easy (I never managed to create so many "soldiers"). Which do you think probably used the Flyweight?

Has aexample of game scenario trees in an article .

Text Editor

Another classic example is the use formatting data in a text editor. It is common for multiple snippets to have the same formatting. Why create an object saying all characteristics of that stretch if another stretch has exactly the same characteristic?

In extreme cases would need an object for each character of the text. That would be crazy. Anything that is repeated can use only one object and everything that needs that formatting the reference.

See an implementation simplified .

Other examples

In the Wikipedia article linked in the question has some examples that demonstrate how the mechanism works. There is an example of a coffee service. Each order served has to reference a coffee flavor, each flavor has its object. But you don't have to create an equal coffee flavor for every order. If you have 10 requests that ask for Espresso, there is only one Espresso.

Think about stock: when we talk about a product, we speak of it in an abstract sense, in something that is specified. We do not talk about every physical item that exists in the company. At this point you don't have to create a product object for each existing physical item. Even if you need control of the single physical product, it doesn't need to have all the product data on the object, this can be shared. Something like this:

class Produto { // existirão alguns, talvez milhares
    int Id;
    string Nome;
    decimal Preco;
    Cor Cor;
    .
    .
    .
}

class Item { // potencialmente existirão milhões
    int Id;
    int ProdutoId; //compõe aqui
    string Serial;
    DateTime Validade;
}

Has a website that talks about all patterns in a well-described way, with UML and examples. see the Flyweight .

Has another with a slightly different approach .

It is curious that many design patterns people use and do not even notice. Those are the best.

 20
Author: Maniero, 2020-11-13 13:20:28