Click here to Skip to main content
15,891,136 members
Articles / All Topics

FlyWeight

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
8 Feb 2010CPOL2 min read 13.1K   4   6
FlyWeight

Imagine that you are developing some gaming software. You 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 a very passionate gamer, he could send requests very frequently. In this case, your application will be creating dozens of instances for each of the Units. 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 leads 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?

FlyWeight

1. Simplest Way With Creating Objects Each Time

We have base class Unit:

C#
public class Unit {
    protected String name;
    protected int health;
    protected String picture;
    
    public void setName(String name) {
    this.name = name;
    }
    public String getName() {
    return name;
    }
    public void setHealth(int health) {
    this.health = health;
    }
    public int getHealth() {
    return health;
    }
    public void setPicture(String picture) {
    this.picture = picture;
    }
    public String getPicture() {
    return picture;
    }
}

And two derived - Dog and Dragon. To make those objects more weightful, I added a picture to them. In my case, that is only a very long string.

C#
public class Dog extends Unit{
    public Dog(){
        name = "dog";
        health = 30;
        
        for(int i = 0; i < 100; ++i)
            picture += "I don't want to load actual image, but if we will be" +
            "creating a lot of strings on each of the Unit this could be very" +
            "resource taking operation.";
    }
}

And our parser executes code which looks like:

C#
public class Parser {
    public ArrayList<Unit> parse(){
    
    ArrayList<Unit> result = new ArrayList<Unit>();

    for(int i = 0; i < 150; ++i)
        result.add(new Dragon());
    
    for(int i = 0; i < 600; ++i)
        result.add(new Dog());
    
    System.out.println("Dogs and Dragons are parsed.");
    
    return result;
    }
}

We want to create only 150 Dragons and 600 Dogs and this takes 28 MB of memory.

2. How Does FlyWeight Work?

Let's introduce UnitsFactory. Responsibility of this factory is to manage creation of the concrete flyweight objects (Dogs and Dragons). It verifies if the object has already been created and in this case, it just returns created and if not, it creates a new one and returns it. See:

C#
public class UnitsFactory {
    
    private static Map<Class, Unit> _units = new WeakHashMap<Class, Unit>();
        
    public static Dog createDog(){
    Class dogClass = Dog.class;
    
    if(! _units.containsKey(dogClass))
        _units.put(dogClass, new Dog());
    
    return (Dog) _units.get(dogClass);
    }
    
    public static Dragon createDragon(){
    Class dragonClass = Dragon.class;
    
    if(! _units.containsKey(dragonClass))
        _units.put(dragonClass, new Dragon());
    
    return (Dragon) _units.get(dragonClass);    
    }
}

Let's take a look at the UML diagram of our code:

UnitsFactory corresponds to FlyweightFactory, Unit - for Flyweight. Dog, Dragon corresponds to concrete Flyweights in the GoF FlyWeitght naming.

Now we will make a change to our parser to use Factory and will see how much of memory it will take. But now, we are going to create 1500 Dragons and 60000 Dogs, probably your gamer is much quicker than you think.

C#
for(int i = 0; i < 1500; ++i)
    result.add(UnitsFactory.createDragon());

for(int i = 0; i < 60000; ++i)
    result.add(UnitsFactory.createDog());

And this takes only about 5 MB of memory:

What Have I Learned Regarding Java?

I know that corresponding to C# Dictionary is Map in Java, and there are few concrete maps like this on this good picture:

Hope this was a good story!

Go to My Design Patterns Table

This article was originally posted at http://andriybuday.blogspot.com/feeds/posts/default

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer SoftServe
Ukraine Ukraine
I'm very pragmatic and self-improving person. My goal is to become successful community developer.
I'm young and love learning, these are precondition to my success.

Currently I'm working in dedicated Ukrainian outsourcing company SoftServe as .NET developer on enterprise project. In everyday work I'm interacting with lot of technologies which are close to .NET (NHibernate, UnitTesting, StructureMap, WCF, Win/WebServices, and so on...)

Feel free to contact me.

Comments and Discussions

 
QuestionSo all the units have the same health? Pin
fredito17-Feb-10 3:06
fredito17-Feb-10 3:06 
AnswerRe: So all the units have the same health? Pin
Andriy Buday17-Feb-10 21:51
Andriy Buday17-Feb-10 21:51 
GeneralRe: So all the units have the same health? Pin
fredito18-Feb-10 3:15
fredito18-Feb-10 3:15 
Questioncan you explain...? Pin
Herre Kuijpers8-Feb-10 21:22
Herre Kuijpers8-Feb-10 21:22 
i'm not too familiar with java, however in your article you point out there is a major difference between the memory usage with respect to the approach used.

I fail to understand why in the first method the creation of a mere 750 objects would take 26MB of memory
while in the second approach the creation of 61500 objects would take only 5MB....
can you explain please?

tnx
Herre

AnswerRe: can you explain...? Pin
Andriy Buday8-Feb-10 23:36
Andriy Buday8-Feb-10 23:36 
GeneralRe: can you explain...? Pin
Herre Kuijpers10-Feb-10 21:21
Herre Kuijpers10-Feb-10 21:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.