Flyweight Design Pattern

Flyweight design pattern supports sharing of objects. In project, sometimes we have similar kinds of objects. Each object have two types of data.

  1. Intrinsic: This data is unique in all objects.
  2. Extrinsic: This data is common in all objects.

Flyweight pattern gives you a pattern to design these objects lightweight by sharing the extrinsic data to an external object. We store extrinsic data to an external object and use that external object in all our objects. We only make one instance of the external object and that is shared by all the objects.

Structure

Flyweight Pattern

Participants

IFlyweight: Defines an interface having a single method SetExtrinsicData

ConcreteFlyweight: Implements the interface IFlyweight and contains intrinsic data.

FlyweightFactory: Factory manages the flyweight objects. If the flyweight object already exists in the cache then return the flyweight object else create a new flyweight, add it to cache and return returns the new flyweight object.

Example

Flyweight Pattern Example

IReport contains single method name SetCompanyInformation. Two reports ReportA and ReportB implements IReport interface. Both reports have their internal data in ReportName variable. ReportFactory implements the factory design pattern and return single report. In the ReportFactory we have maintained a cache. If the report does not exists in cache then create a new report, add it to cache, and then return to the client. If the report already exists in cache then return it directly from cache.

Below is the implementation of above diagram in C#.


class Program
{
    static void Main(string[] args)
    {
        CompanyInformation company = new CompanyInformation();
        company.CompanyName = "ABC Company";
        company.Address = "Company Address";

        var reportA = ReportFactory.GetReport("A");
        reportA.SetCompanyInformation(company);

        var reportA1 = ReportFactory.GetReport("A");
        reportA1.SetCompanyInformation(company);

        var reportB = ReportFactory.GetReport("B");
        reportB.SetCompanyInformation(company);

        company.CompanyName = "Z Company";
    }
}

public interface IReport
{
    void SetCompanyInformation(CompanyInformation company);
}

public class ReportA : IReport
{
    private CompanyInformation company;

    public string ReportName { get; set; }

    public CompanyInformation CompanyInformation
    {
        get
        {
            return this.company;
        }
    }

    public void SetCompanyInformation(CompanyInformation company)
    {
        this.company = company;
    }
}

public class ReportB : IReport
{
    private CompanyInformation company;

    public string ReportName { get; set; }

    public CompanyInformation CompanyInformation
    {
        get
        {
            return this.company;
        }
    }

    public void SetCompanyInformation(CompanyInformation company)
    {
        this.company = company;
    }
}

public class CompanyInformation
{
    public string CompanyName { get; set; }
    public string Address { get; set; }
}

public class ReportFactory
{
    static Dictionary<string, IReport> reports = new Dictionary<string, IReport>();

    public static IReport GetReport(string key)
    {
        if (reports.Keys.Contains(key))
        {
            return reports[key];
        }
        switch (key)
        {
            case "A":
                IReport reportA = new ReportA();
                reports.Add(key, reportA);
                return reportA;
            case "B":
                IReport reportB = new ReportB();
                reports.Add(key, reportB);
                return reportB;

        }
        return null;
    }
}