Skip to main content

Flyweight Design Pattern - C#

Flyweight pattern falls under Structural Pattern of Gang of Four (GOF) Design Patterns in .Net. Flyweight pattern try to reuse already existing similar kind objects by storing them and creates new object when no matching object is found. In this article, I would like share what is flyweight pattern and how is it work?


What is Flyweight Pattern

Flyweight pattern is used to reduce the number of objects created, to decrease memory and resource usage. As a result it increase performance.
Flyweight pattern try to reuse already existing similar kind objects by storing them and creates new object when no matching object is found.
The flyweight pattern uses the concepts of intrinsic and extrinsic data.
Intrinsic data is held in the properties of the shared flyweight objects. This information is stateless and generally remains unchanged, if any change occurs it would be reflected among all of the objects that reference the flyweight.
Extrinsic data is computed on the fly means at runtime and it is held outside of a flyweight object. Hence it can be stateful.

Flyweight Pattern - UML Diagram & Implementation

The UML class diagram for the implementation of the flyweight design pattern is given below:
The classes, interfaces and objects in the above UML class diagram are as follows:
  1. Flyweight

    This is an interface which defines the members of the flyweight objects.
  2. ConcreteFlyweight

    This is a class which Inherits from the Flyweight class.
  3. UnsharedFlyweight

    This is a class which Inherits from the Flyweight class and enables sharing of information, it is possible to create instances of concrete flyweight classes that are not shared.
  4. FlyweightFactory

    This is a class which holds the references of already created flyweight objects. When the GetFlyweight method is called from client code, these references are checked to determine if an appropriate flyweight object is already present or not. If present, it is returned. Otherwise a new object is generated, added to the collection and returned.

C# - Implementation Code

  1. public class FlyweightFactory
  2. {
  3. private Hashtable _flyweights = new Hashtable();
  4. public Flyweight GetFlyweight(string key)
  5. {
  6. if (_flyweights.Contains(key))
  7. {
  8. return _flyweights[key] as Flyweight;
  9. }
  10. else
  11. {
  12. ConcreteFlyweight newFlyweight = new ConcreteFlyweight();
  13. // Set properties of new flyweight here.
  14. _flyweights.Add(key, newFlyweight);
  15. return newFlyweight;
  16. }
  17. }
  18. }
  19. public interface Flyweight
  20. {
  21. void StatefulOperation(object o);
  22. }
  23. public class ConcreteFlyweight : Flyweight
  24. {
  25. public void StatefulOperation(object o)
  26. {
  27. Console.WriteLine(o);
  28. }
  29. }
  30. public class UnsharedFlyweight : Flyweight
  31. {
  32. private object _state;
  33. public void StatefulOperation(object o)
  34. {
  35. _state = o;
  36. Console.WriteLine(o);
  37. }
  38. }

Flyweight Pattern - Example

Who is what?

The classes, interfaces and objects in the above class diagram can be identified as follows:
  1. ShapeObjectFactory- FlyweightFactory class.
  2. IShape - Flyweight interface.
  3. Circle & Rectabgle - ConcreteFlyweight class.

C# - Sample Code

  1. /// <summary>
  2. /// The 'Flyweight' interface
  3. /// </summary>
  4. interface IShape
  5. {
  6. void Print();
  7. }
  8.  
  9. /// <summary>
  10. /// A 'ConcreteFlyweight' class
  11. /// </summary>
  12. class Rectangle : IShape
  13. {
  14. public void Print()
  15. {
  16. Console.WriteLine("Printing Rectangle");
  17. }
  18. }
  19.  
  20. /// <summary>
  21. /// A 'ConcreteFlyweight' class
  22. /// </summary>
  23. class Circle : IShape
  24. {
  25. public void Print()
  26. {
  27. Console.WriteLine("Printing Circle");
  28. }
  29. }
  30.  
  31. /// <summary>
  32. /// The 'FlyweightFactory' class
  33. /// </summary>
  34. class ShapeObjectFactory
  35. {
  36. Dictionary<string, IShape> shapes = new Dictionary<string, IShape>();
  37.  
  38. public int TotalObjectsCreated
  39. {
  40. get { return shapes.Count; }
  41. }
  42.  
  43. public IShape GetShape(string ShapeName)
  44. {
  45. IShape shape = null;
  46. if (shapes.ContainsKey(ShapeName))
  47. {
  48. shape = shapes[ShapeName];
  49. }
  50. else
  51. {
  52. switch (ShapeName)
  53. {
  54. case "Rectangle":
  55. shape = new Rectangle();
  56. shapes.Add("Rectangle", shape);
  57. break;
  58. case "Circle":
  59. shape = new Circle();
  60. shapes.Add("Circle", shape);
  61. break;
  62. default:
  63. throw new Exception("Factory cannot create the object specified");
  64. }
  65. }
  66. return shape;
  67. }
  68. }
  69. class Program
  70. {
  71. static void Main(string[] args)
  72. {
  73. ShapeObjectFactory sof = new ShapeObjectFactory();
  74.  
  75. IShape shape = sof.GetShape("Rectangle");
  76. shape.Print();
  77. shape = sof.GetShape("Rectangle");
  78. shape.Print();
  79. shape = sof.GetShape("Rectangle");
  80. shape.Print();
  81. shape = sof.GetShape("Circle");
  82. shape.Print();
  83. shape = sof.GetShape("Circle");
  84. shape.Print();
  85. shape = sof.GetShape("Circle");
  86. shape.Print();
  87. int NumObjs = sof.TotalObjectsCreated;
  88. Console.WriteLine("\nTotal No of Objects created = {0}", NumObjs);
  89. Console.ReadKey();
  90. }
  91. }

Flyweight Pattern Demo - Output

When to use it?

  1. Flyweight is used when there is a need to create a large number of objects of almost similar nature and storage cost is high.
  2. A few shared objects can replace many unshared ones.
  3. Most of the state can be kept on disk or calculated at runtime.

Comments

Popular posts from this blog

Accessing File Stored in Windows Azure Blob Storage Using jQuery

Did you know it was possible to access the Windows Azure Blob Storage directly from JavaScript, for example using jQuery? At first, it sounds obvious, since Blobs are after all accessible from a public UR. But in practice, there is a very big hurdle: the Web browser’s Same Origine Policy or SOP, that restricts JavaScript code to accessing resources originating from the same site the script was loaded from. This means that you will never be able to load a Windows Azure Blob using XMLHttpRequest for example! Fortunately, there is a popular workaround called JSONP (“JSON with Padding”). The idea behind this technique is that the script tag is not submitted to the SOP: an HTML page can thus load a JavaScript file from any site. So, if you expose your data in an “executable” form in JavaScript, a page will be able to load this data using a script tag. For example: <script type=”text/javascript” src=”http://www.sandeepknarware.in/exemple.jsonp”> </script> But how can ...

Support for debugging lambda expressions with Visual Studio 2015

Anyone who uses LINQ (or lambdas in general) and the debugger will quickly discover the dreaded message “Expression cannot contain lambda expressions”. Lack of lambda support has been a limitation of the Visual Studio Debugger ever since Lambdas were added to C# and Visual Basic.  With visual studio 2015 Microsoft has added support for debugging lambda expressions. Let’s first look at an example, and then I’ll walk you through current limitations. Example To try this yourself, create a new C# Console app with this code: using System.Diagnostics; using System.Linq; class Program { static void Main() { float[] values = Enumerable.Range(0, 100).Select(i => (float)i / 10).ToArray(); Debugger.Break(); } } Then compile, start debugging, and add “values.Where(v => (int)v == 3).ToArray()” in the Watch window. You’ll be happy to see the same as what the screenshot above shows you. I am using Visual Studio 2015 Preview and it has some limitati...

gcAllowVeryLargeObjects Element

There are numerous new features coming with .NET 4.5 and here, on this blog, you can find several posts about it. But the feature we are goint to talk about today is very exciting, because we were waiting for it more than 10 years. Since .NET 1.0 the memory limit of .NET object is 2GB. This means you cannot for example create array which contains elements with more than 2GB in total. If try to create such array, you will get the OutOfMemoryException. Let’s see an example how to produce OutOfMemoryException. Before that Open Visual Studio 2012, and create C# Console Application, like picture below. First lets create simple struct with two double members like example below: 1 2 3 4 5 6 7 8 9 10 11 12 public struct ComplexNumber {      public double Re;      public double Im;      public ComplexNumber( double re, double im)      {    ...