Design Patterns Series 8 - Flyweight Pattern

This post will talk about another pattern is all about restricting object creation like Singleton Pattern, but this time it gives the rest of your code the feeling of multiple objects.

Flyweight Pattern :

It is called flyweight because instead of having to work with many massive, individuals objects, you reduce them to a smaller set of more generic objects, that can be configured at runtime to look like more plentiful, massive objects. Each massive object consumes system resources, by extracting what is generic from those massive objects and relying on runtime configuration to mimic those massive objects, you save the system resources.

You take all the specialized contents out of the massive objects to create flyweight objects. When you do that, you end up with more-generic objects, and you can reduce the number you need - possibly down to just one - which can be configured as need at run time to mimic the larger set of more massive objects.

The Flyweight pattern must use sharing to support large number of line-grained objects efficiently. A flyweight is a shared object that can be used in multiple contexts simultaneously. The flyweight acts as an independant object in each context - it's distinguishable from an instance of the object that's not shared.

Suppose you have a large set of massive objects. You remove from those objects all the specialized, instance specific contents that you can to end up with a shareable object, a flyweight , acts as a template. That template object can then be configured at runtime by passing it all the specialized contents it needs to appear like one of the more massive objects.

If you want to display the hotels information like names, stars, and users rates average about each hotel, That means the hotel object is a massive object and will consume more system resources. The Hotel class as follows
Public Class Hotel
{
   public Hotel(Int32 star)
   {
      this.Stars = star;
   }

   public Int32 ID{ get; set;}
   public String Name{ get; set;}
   public Int32 Stars{ get; set;}
   public Int32[] UserRates{ get; set;}

   public Double Rate
   {
      get
      {
         Double totalRate = 0;
         for(Int32 i = 0 ; i < this.UserRates.Length ; i++)
         {
            totalRate += this.UserRates[i];
         }
         return Math.Round(((totalRate)/(this.UserRates.Length)) , 2);
      }
   }
}
note Hotel class constructor. To use the flyweight pattern to display The rate of each hotel assume we have an array of hotels names, an array for hotel rates, and the stars of all hotels

String[] names = {"Hilton" , "Sheraton" , "4Seasons"};
Int32[][] hotelsRates= {new []{5,2} , new []{4,1,5} , new []{5,5,5,1} };
Int32 stars = 5;
Now we will display the hotels rates using flyweight object
Hotel _hotel = new Hotel(stars);

for (Int32 x = 0; x < names.Length; x++)
{
     _hotel.Name = names[x];
     _hotel.UserRates = hotelsRates[x];

     Console.WriteLine(_hotel.Name + " is a "+_hotel.Stars + " star hotel and its user rate is " + _hotel.Rate);
}
As we sees in the previoius example, all hotels have the same number of stars that we passed into the constructor of Hotel class, this means the number of stars is the generic feature which we extracted from the massive hotel object, then we created the flyweight object(_hotel) and we configured it inside the for loop at run time.

Much like the Singleton Pattern, the idea behind  the Flyweight pattern is to control object creation and limit the number of objects you need.

If your code uses multiple threads, you can avoid creating too many flyweight objects by taking the object creation process away from the new operator in the same way you did with singletons. You can create the flyweight object when the class is first loaded, make the constructor private, and allow object creation only through a CreateInstance method

Flyweight Pattern Drawbacks:
  1. The main issue is that it can take some time to configure a flyweight object, and if you are always swapping configurations, you can lose much of the performance gains you hoped to achieve.
  2. Because you are extracting a generic template class from your existing objects in order to create flyweight objects, you are adding another layer of programming  which can make the maintenance and extension harder.

you can download the full source code here

Comments

Popular posts from this blog

Android : How to change progress bar color at runtime programmatically?

How to fire RowCommand event of nested GridView?

ASP.Net MVC : Conditional Validation using ValidationAttribute