CHAPTER 12 ■ ENTERPRISE PATTERNS
A logical strategy is more flexible, but also more labor intensive, in terms of both setup and
maintenance. You can see an example of this approach in the “Application Controller” section.
You saw an example of a command factory that used a physical strategy in the last chapter. Here is a
slight variation that uses reflection for added safety:
namespace woo\command;
//...
class CommandResolver {
private static $base_cmd;
private static $default_cmd;
function __construct() {
if (! self::$base_cmd ) {
self::$base_cmd = new \ReflectionClass( "\woo\command\Command" );
self::$default_cmd = new DefaultCommand();
}
}
function getCommand( \woo\controller\Request $request ) {
$cmd = $request->getProperty( 'cmd' );
$sep = DIRECTORY_SEPARATOR;
if (! $cmd ) {
return self::$default_cmd;
}
$cmd=str_replace( array('.', $sep), "", $cmd );
$filepath = "woo{$sep}command{$sep}{$cmd}.php";
$classname = "woo\command\{$cmd}";
if ( file_exists( $filepath ) ) {
@require_once( "$filepath" );
if ( class_exists( $classname) ) {
$cmd_class = new ReflectionClass($classname);
if ( $cmd_class->isSubClassOf( self::$base_cmd ) ) {
return $cmd_class->newInstance();
} else {
$request->addFeedback( "command '$cmd' is not a Command" );
}
}
}
$request->addFeedback( "command '$cmd' not found" );
return clone self::$default_cmd;
}
}
This simple class looks for a request parameter called cmd. Assuming that this is found, and that it
maps to a real class file in the command directory, and that the class file contains the right kind of class,
the method creates and returns an instance of the relevant class.
If any of these conditions are not met, the getCommand() method degrades gracefully by serving up a
default Command object.