The Flyweight pattern is a structural design pattern used to reduce the memory usage of objects by sharing common data among similar objects. It is particularly useful when dealing with a large number of objects that have similar states, as it helps minimize the memory footprint by reusing shared state.

Key Characteristics:

  • Shared State: Shares common data among objects to avoid duplication.
  • Intrinsic State: The data that is shared among objects.
  • Extrinsic State: The data that varies between objects and is managed by the client code.

How It Works:

  • Flyweight Interface: Defines the interface for flyweight objects, including methods for managing shared and unique states.
  • Concrete Flyweight: Implements the Flyweight interface and manages the intrinsic state that is shared among multiple objects.
  • Flyweight Factory: Manages the creation and reuse of flyweight objects. It ensures that shared instances are used appropriately.
  • Client: Uses flyweight objects, providing any extrinsic state as needed.

Example in PHP:

  // Flyweight Interface
interface Flyweight {
    public function operation($extrinsicState);
}

// Concrete Flyweight
class ConcreteFlyweight implements Flyweight {
    private $intrinsicState;

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

    public function operation($extrinsicState) {
        return "Intrinsic State: " . $this->intrinsicState . ", Extrinsic State: " . $extrinsicState . "\n";
    }
}

// Flyweight Factory
class FlyweightFactory {
    private $flyweights = [];

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

// Client Code
$factory = new FlyweightFactory();

$flyweight1 = $factory->getFlyweight("Shared State 1");
echo $flyweight1->operation("Unique State A"); // Output: Intrinsic State: Shared State 1, Extrinsic State: Unique State A

$flyweight2 = $factory->getFlyweight("Shared State 1");
echo $flyweight2->operation("Unique State B"); // Output: Intrinsic State: Shared State 1, Extrinsic State: Unique State B

$flyweight3 = $factory->getFlyweight("Shared State 2");
echo $flyweight3->operation("Unique State C"); // Output: Intrinsic State: Shared State 2, Extrinsic State: Unique State C
  

Explanation:

  1. Flyweight Interface: Flyweight defines the operation() method that concrete flyweight classes will implement. This method takes the extrinsic state as a parameter.
  2. Concrete Flyweight: ConcreteFlyweight stores the intrinsic state and implements the operation() method. The intrinsic state is shared among objects.
  3. Flyweight Factory: FlyweightFactory manages the creation and reuse of flyweight objects. It ensures that objects with the same intrinsic state are shared.
  4. Client Code: The client code interacts with the FlyweightFactory to get instances of ConcreteFlyweight and provides the extrinsic state when calling operation().

Benefits:

  • Memory Efficiency: Reduces memory usage by sharing common data among objects.
  • Performance: Can improve performance by reusing existing objects instead of creating new ones.

Use Cases:

  • Large Numbers of Objects: When dealing with a large number of similar objects that share common state.
  • Graphics and UI: For managing graphical objects or UI elements with similar attributes. The Flyweight pattern is valuable for optimizing memory usage and performance by sharing common states among objects, especially when dealing with a large number of similar objects.