Skip to content
Home » Use the Flyweight Design Pattern | PHP Code Examples in 2023

Use the Flyweight Design Pattern | PHP Code Examples in 2023

Using the Flyweight Design Pattern in PHP

The flyweight pattern in PHP is a structural design pattern that optimizes memory usage by sharing common parts of an instance and defining many logical objects based on shared parts. The purpose of this design pattern will be more clear as we discover a real-world example of a movie theatre. So grab your popcorn because it is showtime!

Flyweight Pattern in PHP
Flyweight Pattern in PHP

What is the Flyweight Design Pattern

“The flyweight design pattern is a structural design pattern that allows you to provide many logical instances of a single instance of a class by sharing the common parts of that instance. It helps us optimize memory consumption by reusing identical objects logically.”

Flyweight Pattern in PHP
Flyweight Pattern

Flyweight Design Pattern Example

MovieMax is a hypothetical 3D cinema in the states. It has become popular this year and now they want to sell tickets online. Besides, they also want to enable customers to select available seats in the theatre. So, they want us to implement that feature using a graphical user interface as follows.

cinema-seats

That’s doable. Let’s design the software modules and bring this idea to life.

MovieMax Application Design

moviemax-architecture
MovieMax Architecture

So, the two classes here: Theatre & Seat are the main entities. Seat, of course, represents a seat entity and features certain attributes.

  • coords (short for co-ordinates, determines seat position) 
  • selected (boolean to determine if a seat has already been picked)
  • sprite (image asset for a seat, two sprites: a red and green for a free and selected seat respectively)

Theatre refers to an array of Seat objects meaning that it can have any number of seats that it can draw on the canvas. So, the implementation doesn’t cap the number of seats which can be initialized because after all number of seats varies in different theatres, varies between 100 to 250 seats.

But there’s a catch! While everything seems okay with the design and its implementation, there is a problem or probably a bug that has been bothering users. 

Problem #1: Intrinsic & extrinsic data

So, we tested this application rigorously on our development machines. The simulation worked fine but we have been informed that the application becomes sluggish as it renders more and more theatre rooms (3000+ seats).

On closer inspection, it was revealed that the application eats up RAM fiercely as the number of seats grows. It also seems that our test had a limited scope but the reality was quite different. So, here’s what performance statistics say after another stress test for 5000 seats.

max-memory-usage

The program crashed before it even reaches 4000 and that’s because RAM memory exhausts quickly and the seat objects no longer fit in there. This means that the application is not optimized.

Problem #2: Intrinsic state & immutability

We also need to make sure that the intrinsic state is immutable because it may be used throughout the application and we don’t want any external class to mutate it otherwise what’s the difference then?

So, it has to be initialized by a constructor and there shouldn’t be any getters and setters that could mutate the intrinsic data in any way. 

 With all that said, let’s dig in deep and try to understand what can be optimized.

Flyweight Design Pattern to the Rescue 🙂

Let’s revisit the Seat class. In there, we had two types of data.

  • Common and recurring for all the seat objects (sprite)
  • Unique for every seat object (coords & selected)

Let’s call the former intrinsic and the latter extrinsic. Intrinsic is the same for all seat objects (seats can have either of the two sprites out of red and green). Extrinsic changes depend on a seat’s position and whether it is available or booked.

So, the main problem here is that we are loading sprites again and again for the seat objects which otherwise could be reused. For instance, using 3000 identical sprites for 3000 seats is a total memory wastage.

We should reuse intrinsic state/data somehow to use memory more optimally. That’s the idea.

The extrinsic state is not constant and is usually changed by an external entity (Theatre). So, ideally, there has to be a distinction or a separation between intrinsic and extrinsic attributes. Something similar to the following design.

Flyweight Pattern in PHP

Introducing Flyweight

The flyweight pattern suggests that only the intrinsic state should stay in the class while the extrinsic state should be strapped out to a separate class. A class which has an immutable intrinsic state is called Flyweight.

Flyweight Pattern in PHP

A huge win for Flyweight is reusability. We can initialize fewer Flyweight objects and reuse them when necessary. Another feature is that the state is immutable and is set at the time of initializing a Flyweight so that the intrinsic state remains constant throughout.

About the extrinsic state, it has to change over time and that’s why we keep them in a separate class. In the flyweight pattern, we can call this class generically Context. 

Using Flyweight we can reduce memory consumption down to approximately 1MB and that’s a huge difference given the fact that we were using 5GB before.

optimized-memory

Cool, isn’t it? A simple tweak can make a huge impact. 

Benefits of the Flyweight Design Pattern

  • Helps optimize memory usage by reusing flyweight objects.
  • Define an entity with some intrinsic state that can be reused in more than one context. 

Complete Architecture | Flyweight Design Pattern in PHP

Flyweight Pattern in PHP
Flyweight Pattern in PHP

Flyweight Design Pattern PHP Code Example

The following code is a complete example of using the flyweight pattern in PHP.

<?php


/*
This is the flyweight class. It includes the instrinsic state of the seat entity
We intialize a few of these objects and reuse them in the program because
the state of these objects tend to be the same and there is no need to define
similar objects again and again
*/
class SeatType {


    private $sprite;


    public function __construct($sprite) {
        $this->sprite = $sprite;
    }


    function draw($coords, $canvas) {
        /*
        Uses the sprite and places it on the canvas at the specified coordinates (x, y)
        */
    }
 }


/*
This is the context class. It includes the extrinsic state of the seat entity
It has a reference the flyweight objects. Different context objects can refer to the same
flyweight object
*/
class Seat {


    private  $coords;
    private  $selected;
    private  $seatType;


    public function __construct($coords, $selected, $seatType) {
        $this->coords   = $coords;
        $this->selected = $selected;
        $this->seatType = $seatType;
    }


    function draw($canvas) {
        $this->seatType->draw($this->coords, $canvas);
    }
}


class Theatre {


    private $seats;
   
    public function __construct($seats) {
        $this->seats = $seats;
    }


    function addSeat($coords, $selected, $sprite) {


        $seatType = new SeatType($sprite);


        $seat = new Seat($coords, $selected, $seatType);


        $this->seats[] = $seat;
    }


    function draw($canvas) {


        foreach($this->seats as $seat) {
            $seat->draw($canvas);
        }
    }
}
?>

Pros and Cons of the Flyweight Pattern in PHP

ProsCons
Flyweight helps us optimize memory usage by reusing redundant objects having an identical and constant internal state.Increases code complexity by defining extra classes like Flyweight and Context.
We can reuse flyweight objects in different contexts. Logically distinct flyweight objects cannot behave independently because they are after all similar objects in memory.
Centralized state for a set of objects in one location

Where is the Flyweight Pattern Used?

  • Your program uses a large number of objects that are similar in terms of attributes and operations (intrinsic state).
  • You want to optimize memory usage using flyweight objects.
  • You want to reduce the number of objects at runtime. 

Frequently Asked Questions on the Flyweight Design Pattern

What is the flyweight pattern?

The flyweight pattern is a structural design pattern that allows you to provide many logical instances of a single instance of a class by sharing the common parts of that instance. It helps us optimize memory consumption by reusing identical objects logically.

What does the flyweight pattern do?

The flyweight pattern defines a class that aggregates the common parts of an instance and shares them by defining fewer numbers of instances and then using them logically across the application. The use of a limited number of objects uses less memory.

Flyweight vs singleton pattern: what is the difference?

Flyweights are objects of the same type with little differences. For example, different dog breeds. 

A singleton object is a global object defined once. For example, database instance.

Using the Flyweight Pattern in PHP Today

Cool! Flyweight is definitely a worthy optimization technique. Let’s review what we have seen thus far. The flyweight pattern is a structural design pattern that helps in optimizing memory by defining common parts of an object and then sharing it throughout the application. There could be many logical instances but all of them would map to a few flyweights under the hood.

A flyweight class makes a distinction between intrinsic and extrinsic data and keeps the intrinsic data only because that is constant, recurring and identical for more instances. So, we define a few flyweights and then reuse them in the application.

Flyweight significantly reduces memory consumption by defining fewer objects. Just as we have seen in our example. Initially, we had the intrinsic and extrinsic states defined in one class and whenever we had to initialize we also replicated the shared part which otherwise was not necessary because we could have shared it. Consequently, our application started to consume more memory.

Upon inspection, we realized that redefining the recurring data is wasting a lot of space and thus came flyweight into the picture. We defined a Flyweight class and had our constant intrinsic data in there. We had a separate class for extrinsic data and that class used the flyweight instances. As a result, we saw a significant improvement in memory usage.

So, that’s all about it. We hope you are now well aware of the flyweight pattern and can implement it whenever possible.

See you in another design pattern article. Stay tuned at FuelingPHP.

Books on Design Patterns

Want to learn more about Design Patterns? There are many great resources online. We recommend the following books for your collection as they both can teach you the theoretical and the application of using design patterns in your day-to-day programming. Feel free to use the following Amazon affiliate links if you’d like to purchase them and a way to support our efforts.

Design Patterns: Elements of Reusable Object-Oriented Software

Design Patterns: Elements of Reusable Object-Oriented Software book

This is the book that started it all. I believe that every programmer should have a referenced copy to this book at some point in their career. There have been many updates and excellent newer content through the years, but this is a classic. It still stands the test of time and is just as relevant for today as it was in the original printing in the 90s.

Check it out on amazon

Learning PHP Design Patterns

This is an excellent book to go beyond the theory and apply it to writing good PHP code. Learning PHP Design Patterns is published by the popular O’Reilly media company. O’Reilly consistently publishes some of the most useful reference material related to software development. They are known to provide materials that thoroughly cover a topic in a way that is simple to understand. I recommend this book to every PHP developer.

Check it out on amazon

Want to see our full review of books on design patterns? Read our huge review article on over 15 design pattern books.

Design Patterns in PHP Learning Series.

This article is part of our series of design patterns in PHP. We are going through all of the patterns and showing how they can help you build better applications. Browse through our full list of patterns below.