Flyweight Design Pattern

Flyweight Design Pattern


Do we have too many part objects.


When to use this pattern:


Use sharing to support large numbers of fine-grained objects efficiently.

The strategy of replacing heavy-weight widgets with light-weight gadgets.


Problem


Designing objects down to the lowest levels of system “granularity” provides optimal flexibility, but can be unacceptably expensive in terms of performance and memory usage.


Each “flyweight” object is divided into two pieces: the state-dependent (extrinsic) part, and the state-independent (intrinsic) part. Intrinsic state is stored (shared) in the Flyweight object. Extrinsic state is stored or computed by client objects, and passed to the Flyweight when its operations are invoked.

The client restrains herself from creating Flyweights directly, and requests them from the Factory. Each Flyweight cannot stand on its own. Any attributes that would make sharing impossible must be supplied by the client whenever a request is made of the Flyweight.


The Ant, Locust, and Cockroach classes can be “light-weight” because their instance-specific state has been de-encapsulated, or externalized, and must be supplied by the client.


Example

The Flyweight uses sharing to support large numbers of objects efficiently. The public switched telephone network is an example of a Flyweight. There are several resources such as dial tone generators, ringing generators, and digit receivers that must be shared between all subscribers. A subscriber is unaware of how many resources are in the pool when he or she lifts the handset to make a call. All that matters to subscribers is that a dial tone is provided, digits are received, and the call is completed. 


Remove the non-shareable state from the class attributes, and add it the calling argument list of affected methods.


Create a Factory that can cache and reuse existing class instances.


class Gazillion

{

  public:

    Gazillion(int value_one)

    {

        m_value_one = value_one;

        cout << "ctor: " << m_value_one << '\n';

    }

    ~Gazillion()

    {

        cout << m_value_one << ' ';

    }

    void report(int value_two)

    {

        cout << m_value_one << value_two << ' ';

    }

  private:

    int m_value_one;

};


class Factory

{

  public:

    static Gazillion *get_fly(int in)

    {

        if (!s_pool[in])

          s_pool[in] = new Gazillion(in);

        return s_pool[in];

    }

    static void clean_up()

    {

        cout << "dtors: ";

        for (int i = 0; i < X; ++i)

          if (s_pool[i])

            delete s_pool[i];

        cout << '\n';

    }

    static int X, Y;

  private:

    static Gazillion *s_pool[];

};


int Factory::X = 6, Factory::Y = 10;

Gazillion *Factory::s_pool[] = 

{

  0, 0, 0, 0, 0, 0

};


int main()

{

  for (int i = 0; i < Factory::X; ++i)

  {

    for (int j = 0; j < Factory::Y; ++j)

      Factory::get_fly(i)->report(j);

    cout << '\n';

  }

  Factory::clean_up();

}


ctor: 0

00 01 02 03 04 05 06 07 08 09

ctor: 1

10 11 12 13 14 15 16 17 18 19

ctor: 2

20 21 22 23 24 25 26 27 28 29

ctor: 3

30 31 32 33 34 35 36 37 38 39

ctor: 4

40 41 42 43 44 45 46 47 48 49

ctor: 5

50 51 52 53 54 55 56 57 58 59

dtors: 0 1 2 3 4 5

Setup VSCode with Salesforce

Step by Step guide to setup VSCode with Salesforce Install vscode Install Salesforce CLI (developer.salesforce.com/tools/sfdxcli) Perform fo...