Using The Flyweight Pattern In C#

Introduction

 
In today’s article we will look at the Flyweight pattern in C#. This pattern is used to create reusable objects in an efficient manner which can be consumed by different clients.
 
We will also look at a practical example of using this pattern.

What is the Flyweight pattern and when to use it?

 
The Flyweight pattern is one of the structural patterns in C#. This means that it is defined by its structure which is at design time. In the flyweight pattern we simply create a number of related classes and provide the calling client one of the instances based upon the request type of the client. These instances are maintained in an object e.g., Dictionary etc. and provided to the calling client on demand. Hence, we use another pattern inside the flyweight pattern, and this is the factory pattern. Let us look at an example which will make things much clear about this pattern.
 

Using the Flyweight pattern

 
Let us create a simple console application using Visual Studio 2019 Community Edition. We will select the .NET 5 framework for this project.
 
Using the Flyweight pattern in C#
 
Using the Flyweight pattern in C#
 
Using the Flyweight pattern in C# 
 
After this step, remember to select the .NET 5 framework.
 
Using the Flyweight pattern in C# 
 
After this, add a new class called “Flyweight.cs”
 
Using the Flyweight pattern in C#
 
Using the Flyweight pattern in C# 
 
Now, update the code in the two files as below,
 
(Program.cs)
  1. using ConsoleAppFlyWeight;  
  2. using System;  
  3. string empType = "FullTime";  
  4. var factory = new EmployeeTaxFactory();  
  5. var employeeTax = factory.GetEmployeeTaxBracket(empType);  
  6. employeeTax.DisplayTaxBracket();  
  7. empType = "PartTime";  
  8. employeeTax = factory.GetEmployeeTaxBracket(empType);  
  9. employeeTax.DisplayTaxBracket();  
  10. empType = "FullTime";  
  11. employeeTax = factory.GetEmployeeTaxBracket(empType);  
  12. employeeTax.DisplayTaxBracket();  
  13. Console.ReadKey();  
(Flyweight.cs)
  1. using System;  
  2. using System.Collections.Generic;  
  3. namespace ConsoleAppFlyWeight {  
  4.     public interface IEmployeeTax {  
  5.         string EmployeeType {  
  6.             get;  
  7.             set;  
  8.         }  
  9.         int TaxBracket {  
  10.             get;  
  11.             set;  
  12.         }  
  13.         void DisplayTaxBracket();  
  14.     }  
  15.     public class EmployeeTaxFactory {  
  16.         private Dictionary < string, IEmployeeTax > _employeesTax = new();  
  17.         public IEmployeeTax GetEmployeeTaxBracket(string key) {  
  18.             IEmployeeTax employeeTax = null;  
  19.             if (_employeesTax.ContainsKey(key)) {  
  20.                 employeeTax = _employeesTax[key];  
  21.             } else {  
  22.                 switch (key) {  
  23.                     case "FullTime":  
  24.                         employeeTax = new FullTimeEmployee();  
  25.                         break;  
  26.                     case "PartTime":  
  27.                         employeeTax = new PartTimeEmployee();  
  28.                         break;  
  29.                 }  
  30.                 _employeesTax.Add(key, employeeTax);  
  31.             }  
  32.             return employeeTax;  
  33.         }  
  34.     }  
  35.     public class FullTimeEmployee: IEmployeeTax {  
  36.         public string EmployeeType {  
  37.             get;  
  38.             set;  
  39.         }  
  40.         public int TaxBracket {  
  41.             get;  
  42.             set;  
  43.         }  
  44.         public FullTimeEmployee() {  
  45.             EmployeeType = "FullTime";  
  46.             TaxBracket = 1;  
  47.         }  
  48.         public void DisplayTaxBracket() {  
  49.             Console.WriteLine($ "The Tax Bracket is {TaxBracket}");  
  50.         }  
  51.     }  
  52.     public class PartTimeEmployee: IEmployeeTax {  
  53.         public string EmployeeType {  
  54.             get;  
  55.             set;  
  56.         }  
  57.         public int TaxBracket {  
  58.             get;  
  59.             set;  
  60.         }  
  61.         public PartTimeEmployee() {  
  62.             EmployeeType = "PartTime";  
  63.             TaxBracket = 2;  
  64.         }  
  65.         public void DisplayTaxBracket() {  
  66.             Console.WriteLine($ "The Tax Bracket is {TaxBracket}");  
  67.         }  
  68.     }  
  69. }  
When we run the application, we see the below,
 
Using the Flyweight pattern in C# 
 
In the Flyweight.cs file, we create an interface and two concrete classes that each implement this interface. Finally, we create the factory class which is the heart of this pattern in which we check the request type (which can be full time or part time in our example code) and return the particular concrete class. The main difference from a simple factory pattern is that we also maintain this instance in a dictionary object and when a subsequent request comes for this class, we return it from the dictionary. You can put a break point in the factory class and see that when we request for the full-time class the second time it is returned from the dictionary. Hence, I would recommend this pattern only for simple, short span classes.
 

Summary

 
In this article, we looked at the flyweight pattern in C#. We also looked at a practical implementation of this pattern and when we should use this pattern over a standard factory pattern. Happy coding!