Flyweight in PHP
Why read if you can watch?
Watch Flyweight's video tutorialIn 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 clumbsy 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/>";
}
?>
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