Flyweight Design Pattern in PHP

In the flyweight pattern instances of a class which are identical are shared in an implementation instead of creating a new instance of that class for every instance.

This is done largely to assist performance, and works best when a large number of the exact same instance of a class would otherwise be created.

In this example, the FlyweightBook class stores only author and title, with only three possible author title combinations being used by the system, and yet the system may have a large number of duplicate books.

FlyweightFactory is in charge of distributing instances of FlyweightBook, and only creates a new instance when necessary.

<?php

class FlyweightBook {
    private $author;
    private $title;    
    function __construct($author_in, $title_in) {
        $this->author = $author_in;
        $this->title  = $title_in;
    }      
    function getAuthor() {
        return $this->author;
    }    
    function getTitle() {
        return $this->title;
    }
}
 
class FlyweightFactory {
    private $books = array();     
    function __construct() {
        $this->books[1] = NULL;
        $this->books[2] = NULL;
        $this->books[3] = NULL;
    }  
    function getBook($bookKey) {
        if (NULL == $this->books[$bookKey]) {
            $makeFunction = 'makeBook'.$bookKey;
            $this->books[$bookKey] = $this->$makeFunction(); 
        } 
        return $this->books[$bookKey];
    }    
    //Sort of an long way to do this, but hopefully easy to follow.  
    //How you really want to make flyweights would depend on what 
    //your application needs.  This, while a little clumsy looking,
    //does work well.
    function makeBook1() {
        $book = new FlyweightBook('Larry Truett','PHP For Cats'); 
        return $book;
    }
    function makeBook2() {
        $book = new FlyweightBook('Larry Truett','PHP For Dogs'); 
        return $book;
    }
    function makeBook3() {
        $book = new FlyweightBook('Larry Truett','PHP For Parakeets'); 
        return $book;
    }
}
 
class FlyweightBookShelf {
    private $books = array();
    function addBook($book) {
        $this->books[] = $book;
    }    
    function showBooks() {
        $return_string = NULL;
        foreach ($this->books as $book) {
            $return_string .= 'title: "'.$book->getAuthor().'  author: '.$book->getTitle();"
        };
        return $return_string;
    }
}

  writeln('BEGIN TESTING FLYWEIGHT PATTERN');
 
  $flyweightFactory = new FlyweightFactory();
  $flyweightBookShelf1 =  new FlyweightBookShelf();
  $flyweightBook1 = $flyweightFactory->getBook(1);
  $flyweightBookShelf1->addBook($flyweightBook1);
  $flyweightBook2 = $flyweightFactory->getBook(1);
  $flyweightBookShelf1->addBook($flyweightBook2);
 
  writeln('test 1 - show the two books are the same book');
  if ($flyweightBook1 === $flyweightBook2) {
     writeln('1 and 2 are the same');
  } else {
     writeln('1 and 2 are not the same');    
  }
  writeln('');

  writeln('test 2 - with one book on one self twice');
  writeln($flyweightBookShelf1->showBooks());
  writeln('');

  $flyweightBookShelf2 =  new FlyweightBookShelf(); 
  $flyweightBook1 = $flyweightFactory->getBook(2);  
  $flyweightBookShelf2->addBook($flyweightBook1);
  $flyweightBookShelf1->addBook($flyweightBook1);

  writeln('test 3 - book shelf one');
  writeln($flyweightBookShelf1->showBooks());
  writeln('');

  writeln('test 3 - book shelf two');
  writeln($flyweightBookShelf2->showBooks());
  writeln('');

  writeln('END TESTING FLYWEIGHT PATTERN');
 
  function writeln($line_in) {
    echo $line_in."<br/>";
  }

?>

Output

BEGIN TESTING FLYWEIGHT PATTERN

test 1 - show the two books are the same book
1 and 2 are the same

test 2 - with one book on one self twice
title: "Larry Truett author: PHP For Cats"
title: "Larry Truett author: PHP For Cats"

test 3 - book shelf one
title: "Larry Truett author: PHP For Cats"
title: "Larry Truett author: PHP For Cats"
title: "Larry Truett author: PHP For Dogs"

test 3 - book shelf two
title: "Larry Truett author: PHP For Dogs"


END TESTING FLYWEIGHT PATTERN

Code examples