Current Location: Home> Latest Articles> In-depth Analysis of Flyweight Pattern in PHP and Its Applications

In-depth Analysis of Flyweight Pattern in PHP and Its Applications

gitbox 2025-06-28

What is the Flyweight Pattern

The Flyweight pattern is a structural design pattern that reduces memory usage and enhances performance by sharing objects. It is suitable for scenarios with a large number of similar objects, and by sharing the common state of these objects, it helps save memory and reduce the overhead of object creation and destruction.

Principle of the Flyweight Pattern

The core idea behind the Flyweight pattern is to separate objects into two parts: internal state (inherent properties) and external state (extrinsic properties). Internal state remains constant and can be shared among multiple objects, while external state is variable and typically determined by the object's environment.

By sharing internal states, the number of objects can be reduced, which significantly cuts down memory consumption. External states are dynamically passed into the object and modified during use.

Application Scenarios of the Flyweight Pattern

The Flyweight pattern is valuable in the following situations:

Scenario with Many Similar Objects

When a system contains many similar objects, the Flyweight pattern can be used to share internal states, thus reducing memory usage.

When Object Properties Can Be Split into Internal and External States

If an object's properties can be categorized into internal and external states, internal states can be shared, while external states are determined by the environment.

Implementing the Flyweight Pattern

To implement the Flyweight pattern in PHP, follow these basic steps:

First, create a Flyweight Factory, which manages and provides access to shared Flyweight objects.

class FlyweightFactory {
    private $flyweights = [];
    public function getFlyweight($key) {
        if (!isset($this->flyweights[$key])) {
            $this->flyweights[$key] = new ConcreteFlyweight($key);
        }
        return $this->flyweights[$key];
    }
}

Next, define the Flyweight interface.

interface Flyweight {
    public function operation();
}

Then, create the concrete Flyweight objects that implement shared internal and external states.

class ConcreteFlyweight implements Flyweight {
    private $key;
    public function __construct($key) {
        $this->key = $key;
    }
    public function operation() {
        // specific operation logic
    }
}

Advantages and Disadvantages of the Flyweight Pattern

Advantages

  • Memory Savings: By sharing internal states, the number of objects is reduced, lowering memory consumption.
  • Performance Improvement: Reducing the cost of object creation and destruction enhances system performance.

Disadvantages

  • External State Changes Can Affect Shared Objects: Since external states are controlled by the environment, changes to the external state might affect the behavior of shared objects.
  • Limited Object Reusability: If the internal state of objects changes frequently, the degree of sharing decreases, reducing the Flyweight pattern's advantages.

Flyweight Pattern Example

Consider a game development scenario where a character manager needs to handle many character objects. Some character attributes, such as job and skills, are constant, while others, like position and health, change during gameplay.

In this case, the job can be shared as the internal state, while position and health are passed as external states.

class Character {
    private $job;
    private $position;
    private $hp;
    public function __construct($job) {
        $this->job = $job;
    }
    public function setPosition($x, $y) {
        $this->position = "($x, $y)";
    }
    public function setHP($hp) {
        $this->hp = $hp;
    }
    public function display() {
        echo "Job: {$this->job}, Position: {$this->position}, HP: {$this->hp}";
    }
}

Using the Flyweight pattern allows us to reduce the number of character objects, improving memory efficiency and system performance.

$factory = new FlyweightFactory();
$character1 = $factory->getFlyweight('Warrior');
$character1->setPosition(10, 20);
$character1->setHP(100);
$character1->display();
$character2 = $factory->getFlyweight('Mage');
$character2->setPosition(30, 40);
$character2->setHP(80);
$character2->display();

Output:

Job: Warrior, Position: (10, 20), HP: 100
Job: Mage, Position: (30, 40), HP: 80

The output shows that the shared internal state (job) is the same, while the external states (position and HP) differ.