Created
September 15, 2011 09:46
-
-
Save juzna/1218914 to your computer and use it in GitHub Desktop.
Renderers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Movie { | |
const GENRE_HORROR = 1; | |
const GENRE_SCIFI = 2; | |
const GENRE_FAMILY = 3; | |
const GENRE_X0 = 4; // just to have more labels (for performance testing) | |
const GENRE_X1 = 5; | |
const GENRE_X2 = 6; | |
const GENRE_X3 = 7; | |
const GENRE_X4 = 8; | |
const GENRE_X5 = 9; | |
const GENRE_X6 = 10; | |
const GENRE_X7 = 11; | |
const GENRE_X8 = 12; | |
const GENRE_X9 = 13; | |
public $genre; | |
public $name; | |
/** | |
* @param string $name | |
* @param int $genre | |
*/ | |
function __construct($name, $genre) { | |
$this->name = $name; | |
$this->genre = $genre; | |
} | |
} | |
interface IRenderer { | |
/** @return string[] Classes which I can render */ | |
function getRenderables(); | |
/** @param mixed $object @return string */ | |
function render($object); | |
} | |
interface ILabelRenderer extends IRenderer { | |
function renderByIndex($x); | |
function getIndexByLabel($label); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Ancestor for all renderers, makes sure that we render only what's possible to be rendered | |
*/ | |
abstract class AbstractRenderer implements IRenderer { | |
// actual renderer implementation | |
abstract protected function _render($obj); | |
final public function render($object) | |
{ | |
$className = get_class($object); | |
if(!in_array($className, $this->getRenderables())) throw new Exception("Unable to render '$className'"); | |
return $this->_render($object); | |
} | |
} | |
/** | |
* Ancestor for all renderers, which convert numeric property into human readable label | |
*/ | |
abstract class LabelRenderer extends AbstractRenderer implements ILabelRenderer { | |
/** @return string[int] All labels based on integral index */ | |
abstract protected function getLabels(); | |
/** @return string Property of object to be rendered */ | |
abstract protected function getPropertyName(); | |
final protected function _render($obj) { | |
// AbstractRenderer makes sure that object is one of getRenderables | |
$x = $obj->{$this->getPropertyName()}; | |
return $this->renderByIndex($x); | |
} | |
final public function renderByIndex($x) { | |
$tmp = $this->getLabels(); | |
if (isset($tmp[$x])) return $tmp[$x]; | |
else return null; | |
} | |
final public function getIndexByLabel($label) { | |
return array_search($label, $this->getLabels()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Ancestor for all renderers, makes sure that we render only what's possible to be rendered | |
*/ | |
abstract class AbstractRenderer implements IRenderer { | |
protected $renderables; | |
final public function getRenderables() { | |
// just to support the interface | |
return $this->renderables; | |
} | |
// actual renderer implementation | |
abstract protected function _render($obj); | |
final public function render($object) | |
{ | |
$className = get_class($object); | |
if(!in_array($className, $this->renderables)) throw new Exception("Unable to render '$className'"); | |
return $this->_render($object); | |
} | |
} | |
/** | |
* Ancestor for all renderers, which convert numeric property into human readable label | |
*/ | |
abstract class LabelRenderer extends AbstractRenderer implements ILabelRenderer { | |
/** @return string[int] All labels based on integral index */ | |
protected $labels; | |
/** @return string Property of object to be rendered */ | |
protected $propertyName; | |
final protected function _render($obj) { | |
// AbstractRenderer makes sure that object is one of getRenderables | |
$x = $obj->{$this->propertyName}; | |
return $this->renderByIndex($x); | |
} | |
final public function renderByIndex($x) { | |
if (isset($this->labels[$x])) return $this->labels[$x]; | |
else return null; | |
} | |
final public function getIndexByLabel($label) { | |
return array_search($label, $this->labels); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class MovieNameRenderer extends AbstractRenderer { | |
function getRenderables() { | |
return array('Movie'); | |
} | |
function _render($obj) { | |
return $obj->name; | |
} | |
} | |
class MovieGenreRender extends LabelRenderer { | |
function getRenderables() { | |
return array('Movie'); | |
} | |
protected function getPropertyName() { | |
return 'genre'; | |
} | |
protected function getLabels() { | |
return array( | |
Movie::GENRE_HORROR => 'Horror', | |
Movie::GENRE_SCIFI => 'Sci-Fi', | |
Movie::GENRE_FAMILY => 'Family', | |
Movie::GENRE_X0 => 'Dummy 0', | |
Movie::GENRE_X1 => 'Dummy 1', | |
Movie::GENRE_X2 => 'Dummy 2', | |
Movie::GENRE_X3 => 'Dummy 3', | |
Movie::GENRE_X4 => 'Dummy 4', | |
Movie::GENRE_X5 => 'Dummy 5', | |
Movie::GENRE_X6 => 'Dummy 6', | |
Movie::GENRE_X7 => 'Dummy 7', | |
Movie::GENRE_X8 => 'Dummy 8', | |
Movie::GENRE_X9 => 'Dummy 9', | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class MovieNameRenderer extends AbstractRenderer { | |
protected $renderables = array('Movie'); | |
function _render($obj) { | |
return $obj->name; | |
} | |
} | |
class MovieGenreRender extends LabelRenderer { | |
protected $renderables = array('Movie'); | |
protected $propertyName = 'genre'; | |
protected $labels = array( | |
Movie::GENRE_HORROR => 'Horror', | |
Movie::GENRE_SCIFI => 'Sci-Fi', | |
Movie::GENRE_FAMILY => 'Family', | |
Movie::GENRE_X0 => 'Dummy 0', | |
Movie::GENRE_X1 => 'Dummy 1', | |
Movie::GENRE_X2 => 'Dummy 2', | |
Movie::GENRE_X3 => 'Dummy 3', | |
Movie::GENRE_X4 => 'Dummy 4', | |
Movie::GENRE_X5 => 'Dummy 5', | |
Movie::GENRE_X6 => 'Dummy 6', | |
Movie::GENRE_X7 => 'Dummy 7', | |
Movie::GENRE_X8 => 'Dummy 8', | |
Movie::GENRE_X9 => 'Dummy 9', | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$which = @$argv[1]; | |
if(!$which) die("Usage: php test.php methods|properties\n"); | |
require __DIR__ . '/basic.php'; | |
require __DIR__ . "/$which/basic.php"; | |
require __DIR__ . "/$which/definitions.php"; | |
function showList($list, IRenderer $col1, ILabelRenderer $col2) { | |
$counter = 0; | |
foreach($list as $item) { | |
// render and throw away | |
$txt = sprintf("%d: %s (%s)\n", ++$counter, $col1->render($item), $col2->render($item)); | |
// try to test labelToIndex | |
$dummy = $col2->getIndexByLabel($col2->render($item)); | |
if($dummy !== $item->genre) throw new Exception("Assert failed"); | |
} | |
} | |
// Test | |
$start = microtime(true); | |
// Initialize test | |
{ | |
$movies = array(); | |
for ($i = 0; $i < 1e6; $i++) $movies[] = new Movie("Movie $i", rand(1, 13)); | |
showList($movies, new MovieNameRenderer, new MovieGenreRender); | |
} | |
$end = microtime(true); | |
printf("Using $which - duration: %f\n", $end - $start); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment