Skip to content

Instantly share code, notes, and snippets.

@ezimuel
Created June 19, 2012 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ezimuel/2955319 to your computer and use it in GitHub Desktop.
Save ezimuel/2955319 to your computer and use it in GitHub Desktop.
Idea for a Factory abstract class
interface FactoryInterface {
public static function factory($classname, $options = null);
public static function validate($classname);
public static function getClassMap();
}
abstract class AbstractFactory {
public static function factory($name, $options = null)
{
if (!is_string($name)) {
throw new Exception\InvalidArgumentException(sprintf(
'Expecting a string, received "%s"',
(is_object($name) ? get_class($name) : gettype($name))
));
}
$class = self::validate($name);
if ($class === false) {
return false;
}
if (!class_exists($class)) {
return false;
}
return new $class($options);
}
public static function validate($name)
{
$classMap = static::getClassMap();
if (array_key_exists($name, $classMap)) {
if (is_array($classMap[$name])) {
$classname = $classMap[$name][0];
$interface = $classMap[$name][1];
if (in_array($interface, class_implements($classname))) {
return $classname;
} else {
throw new Exception\RuntimeException("The class $classname doesn't implement $interface");
}
}
return $classMap[$name];
}
throw new Exception\RuntimeException("I cannot load the class $name");
}
}
class Foo {
public function hello() {
echo "Hello world!\n";
}
}
class FooFactory extends AbstractFactory implements FactoryInterface {
public static function getClassMap()
{
return array (
'foo' => 'Foo' // if the value is array($class, $interface) the $class must implement the $interface
);
}
}
$foo = FooFactory::factory('foo');
if (!$foo instanceof Foo) {
die("ERROR\n");
}
$foo->hello();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment