What is Flyweight Pattern?

Asked

Viewed 1,626 times

28

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

In accordance with the article from Wikipedia this pattern can be used to reduce memory consumption, but it is not very clear to me what this pattern does and how it is implemented. Would the pattern 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?

1 answer

22


Memory saving

He is a form of cache yes, but it’s more for sharing.

It 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 share of them.

Of course the cache (for Memoization or something similar) usually tries to avoid that a processing already occurred has to occur again. Memory saving may occur, but it is also possible to do the opposite, e.g., keep things in memory that are not even used.

The Flyweight is more intent to save memory.

Performance

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

There can be a gain in processing by not creating so many objects, but nothing expressive. The economy occurs in creation and not in use, which tends to exist in proportion to creation.

There may even be some loss creating something unnecessary.

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

Almost a Singleton

He kind of remembers the Singleton, but it does not 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 necessary, 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 on objects defined at compile time. Two strings identical created at runtime will not be internalized, at least not automatically (see String.intern() and string.Intern()).

As well as the strings, any of these objects are usually immutable, even because if something changes in them, they will have another identity. Having other internal values, it is another object; this changed object can no longer be shared with others who have maintained its values.

There are many cases where part of the object can be shared and part needs something customized. So a mechanism can be used to put the two together. They talk a lot in shared state (Intrinsic) and unshared state (extrinsic). If there were no such separation some objects would always have a different identity and could not be shared.

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

Like most design patterns, 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 about Age of Empires which may have 200 battle units per civilization. On ancient computers it would slow down. Already the Cossacks, that allows 32 thousand units, even in old computers ran easy (I could never create so many "soldiers"). Which one do you think probably used the Flyweight?

Has a example of game scenario trees in an article.

Text editor

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

In extreme cases you would need an object for each character of the text. It would be crazy. Anything that is repeated can use a single object and everything that needs that formatting the reference.

See a simplified implementation.

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 met has to reference a taste of coffee, each flavor has its object. But there is no reason to create the same coffee flavor for each order. If you have 10 requests that ask Espresso, there just needs to be one Espresso.

Think about the stock: when we talk about a product, we talk about it in an abstract sense, in something that is specified. We are not talking about every physical item that exists in the company. At this point there is no reason to create an object of a product for every existing physical item. Even if you need control of the unique physical product, it doesn’t need to have all the product data in the object, it can be shared. Something like that:

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 speaks of all patterns in a well described way, with UML and examples. Look at the Flyweight.

Has another with a slightly different approach.

It’s curious that many design patterns people use and don’t even realize. These are the best.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.