January 17, 2010 Design Patterns, Java
January 17, 2010 Design Patterns, Java
Imagine that you are developing some gaming software. Your write Web client and on each of response you are parsing entire XML to get your game Units. You have some set of types of Units, for example 50 different animals, but when you parse your XML you can get dozens of instances of the same Unit and few dozens of instances of other Unit.
If User of the game is very passionate gamer, he could send requests very frequently. In this case your application will be creating dozens of instances for each of the Unit. But, your units have some static descriptions. For example, Dragon has Attack, initial Health level, and also you need to keep image of the dragon in the object of Dragon.
This all lead to intensive and not efficient memory usage. How could you share common information for all types of Units without creating instances for each individual Unit?
1) Simplest way with creating objects each time.
We have base class Unit:
And two derived – Dog and Dragon. To make those objects more weightfull I added to them picture. In my case that is only very long string.
And our parser executes code which looks like:
We want to create only 150 Dragons and 600 Dogs and this takes 28 Mb of memory.
2) How does FlyWeight work?
Lets introduce UnitsFactory. Responsibility of this factory is to manage creation of the concrete flyweight objects (Dogs and Dragons). It verifies if the object has been already created and in this case it just returns created and if not it creates new one and returns it. See:
Lets take a look on UML diagram of our code:
UnitsFactory corresponds to FlyweightFactory, Unit – for Flyweight. Dog, Dragon corresponds to concrete Flyweights in the GoF FlyWeithgt naming.
Now we will do change to our parser to use Factory and will see how much of memory will it take.
But now we are going to create 1500 Dragons and 60000 Dogs, probably your gamer is quite more quick as you think.
And this takes only about 5 Mb of memory:
What have I learned regarding to of Java?
I know that corresponding to C# Dictionary is Map in Java, and there are few concrete maps like on this good picture:
Hope this was a good story!
Go to: My Design Patterns Table
Markdown | Result |
---|---|
*text* | text |
**text** | text |
***text*** | text |
`code` | code |
~~~ more code ~~~~ |
more code |
[Link](https://www.example.com) | Link |
* Listitem |
|
> Quote | Quote |
1. Quite easy and intuitive pattern. I guess a lot of developers use it even without knowing that it is design pattern. It's kinda "give a cool name to usual thing to make thing cooler" %)
2. I think the example about game is not very good. It is easy, of course, but it fails to convince someone that FlyWeight is important.
Personally, I don't understand the need to do this:
for(int i = 0; i < 1500; ++i)
result.add(UnitsFactory.createDragon());
if you just can store in some map, that you have 1500 instances of dragon:
map[UnitsFactory.createDragon()] = 1500; // what's wrong with this?
I believe this pattern is useful, but provided example fails to present good use case :(
3. It would be great to hear something about differences of different implementations of maps in Java. And, if you are interested in collections, you can check a recently released Google Collections library. There was also some presentation of future additions to Java 7 given by J.Bloch et al. You can check that also, as far as I remember, there was something about collections as well.
Hope my comments are useful and do not discourage you. Nothing personal – just wanting to help you become better blogger/educator ;)
Do you have some really demonstrative example? Please share.
As about collections, thank you for letting me know sources to get more knowledge.
P.S. Thanks for reading my blog. Teach me more :)
Hmm… definitely you know more than me and (what is more important) you do much more work on learning new stuff, so I guess it's you teaching me :) I just like criticize ;)
as for example… I don't know, I must think about it more thoroughly.. But do you agree with me that as for now there is no reason to use this pattern?
Actually my example is taken from real world. I know a guy who wrote a gaming bot to play some online game. In that game he operates with instances of units which has images.
I see my example good, but yea.. I agree that it is not very demonstrative.
I guess you should tell that guy, that he can implement his gaming bot much more memory-efficiently…
Yea… actually he used FlyWeight and this saved him a log of memory.
my point is he could save even more memory by using one counter for each object type, but not 1500 POINTERS to the SAME object. 1500 pointer definitely takes more memory than ONE int :)
Ah.. I gotcha.. I believe that he has more complicated code there. Maybe he need wrap those instanced somewhere when they start to play… for example health level decreases for particular Dragon.
Your idea is good!
Ok, I'm happy we came to consensus! :)
Why do you fire out me here with my bot? :)
It should be said that order of items is important in my program and every creature has it's position on the feild. Thats why i can't store only amount of units. This is first reason for using FlyWeight.
Second reason is that I perform parsing of responses every 300 miliseconds, and there was large memory usage before I understood that I can apply FlyWeight here.
Ofcourse I can use some integer ID for each unit but FlyWeight does the same but more comfortable.
For faster work of my bot I've removed checkings for existing items. All possible units are created when the program start up, and of course they always exists for any reqest.