标签:system sage rect cto turn 就会 return username ima
问题:
如果页面必须处理很多不同的任务,就应该考虑将任务进行封装。封装之后,向系统中增加新任务就会变得简单,并且可以将系统中的各部分分离开来。这时,我们就可以使用命令模式了。
概念:
将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
实现:
1. 类图示例:
2. 代码示例:
//命令对象参数类
class CommandContext
{
private $params = [];
private $error = ‘‘;
public function __construct()
{
$this->params = $_REQUEST;
}
public function addParam($key, $val)
{
$this->params[$key] = $val;
}
public function get($key)
{
return $this->params[$key];
}
public function setError($error)
{
$this->error = $error;
}
public function getError()
{
return $this->error;
}
}
//命令对象基类
abstract class Command
{
abstract public function execute(CommandContext $context);
}
//命令对象具体实现
class LoginCommand extends Command
{
public function execute(CommandContext $context)
{
$manager = Registry::getAccessManager();
$user = $context->get(‘username‘);
$pass = $context->get(‘pass‘);
$userObj = $manager->login($user, $pass);
if(is_null($userObj)) {
$context->setError($manager->getError());
return false;
}
$context->addParam(‘user‘, $userObj);
return true;
}
}
//命令对象具体实现
class FeedbackCommand extends Command
{
public function execute(CommandContext $context)
{
$msgSystem = Registry::getMessageSystem();
$email = $context->get(‘email‘);
$msg = $context->get(‘msg‘);
$topic = $context->get(‘topic‘);
$result = $msgSystem->send($email, $msg, $topic);
if(!$result) {
$context->setError($msgSystem->getError());
return false;
}
return true;
}
}
//命令对象异常类
class CommandNotFoundException extends Exception {}
//命令对象工厂类
class CommandFactory
{
private static $dir = ‘commands‘;
public static function getCommand($action = ‘default‘)
{
if(preg_match(‘/\W/‘, $action)) {
throw new Exception(‘illegal characters in action‘);
}
$class = ucfirst(strtolower($action)) . ‘Command‘;
$file = self::$dir . DIRECTORY_SEPARATOR . $class . ‘.php‘;
if(!file_exists($file)) {
throw new CommandNotFoundException(‘file not found: ‘ . $file);
}
require_once($file);
if(!class_exists($class)) {
throw new CommandNotFoundException(‘class not found: ‘ . $file);
}
$cmd = new $class();
return $cmd;
}
}
//命令对象调用者
class Controller
{
private $context;
public function __construct()
{
$this->context = new CommandContext();
}
public function getContext()
{
return $this->context;
}
public function process()
{
$cmd = CommandFactory::getCommand($this->context->get(‘action‘));
if(!$cmd->execute($this->context)) {
//失败处理
} else {
//成功
}
}
}
//伪造用户请求测试
$controller = new Controller();
$context = $controller->getContext();
$context->addParam(‘action‘, ‘login‘);
$context->addParam(‘username‘, ‘jet‘);
$context->addParam(‘pass‘, ‘888888‘);
$controller->process();
注意:Command对象不应该执行太多的逻辑。它们应该负责检查输入、处理错误、缓存对象和调用其他对象来执行一些必要的操作。
效果:
1. 能比较容易地设计一个命令队列。
2. 在需要的情况下,可以较容易地将命令记入日志。
3. 允许接收请求的一方决定是否要否决请求。
4. 可以很容易地实现对请求的撤销和重做。
5. 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
6. 促进了控制器和领域模型的分离。
7. 更好地组织系统,易于扩展。
标签:system sage rect cto turn 就会 return username ima
原文地址:https://www.cnblogs.com/wujuntian/p/9658420.html