命令模式

命令模式描述:


命令模式的理解

生活中例子:

例子1:  上路边摊吃烤串,和上烤串店吃烤串比较,门店更加好点不容易算错帐,不容易记错客户的要求,等等。

门店中 客户,服务点, 厨师的关系对照设计模式术语怎么理解? 厨师 ===执行类(会烤鱼,烤串,等等); 服务员== 传达命令类/表面执行类(相会客户来说); 菜单=== 命令类; 客户=== 使用命令的地方;

简单的命令模式代码如下:

<?php

interface Command{
    function execute();
}

//具体命令角色,指定接受者执行攻击命令
class AttackCommand implements Command{
    private $receiver;
    function __construct(Receiver $receiver)
    {
        $this->receiver = $receiver;
    }

    function execute()
    {
        // TODO: Implement execute() method.
        $this->receiver->attackAction();
    }
}

//具体名利角色,指定接受者执行防御命令
class DefenseCommand implements Command{
    private $receiver;
    function __construct(Receiver $receiver)
    {
        $this->receiver = $receiver;
    }

    function execute()
    {
        // TODO: Implement execute() method.
        $this->receiver->defenseAction();
    }
}

//接受者,执行具体命令角色的命令
class Receiver{
    private $name;
    function __construct($name)
    {
        $this->name = $name;
    }

    function attackAction(){
        echo $this->name."执行了攻击命令\n";
    }

    function defenseAction(){
        echo $this->name."执行了防御命令\n";
    }

}

//请求者,请求具体命令的执行
class Invoker{
    private $concreteCommand;
    function __construct($concreteCommand)
    {
        $this->concreteCommand = $concreteCommand;
    }

    function executeCommand(){
        $this->concreteCommand->execute();
    }
}

//客户端角色
class Client{
    function __construct()
    {
        $receiverZhao = new Receiver("小明");
        $attackCommand = new AttackCommand($receiverZhao);
        $attackInvoker = new Invoker($attackCommand);
        $attackInvoker->executeCommand();

        $receiverYe = new Receiver("小丽");
        $defenseCommand = new DefenseCommand($receiverYe);
        $defenseInvoker = new Invoker($defenseCommand);
        $defenseInvoker->executeCommand();

    }
}

new Client();

较复杂命令模式如下:

比较上面增加就是 对命令集支持,可以增加,或删除命令,并且同时execute执行多个命令

<?php

interface Command{
    public function execute();
}


/**
 * 多命令接口
 */
interface MacroCommand extends Command{

    /**
     * @param Command $command
     * @return mixed
     * 删除一个成员命令
     */
    public function remove(Command $command);

    /**
     * @param Command $command
     * @return mixed
     * 增加一个成员命令
     */
    public function add(Command $command);
}


class DemoMacroCommand implements MacroCommand{
    private $_commandList;

    public function __construct()
    {
        $this->_commandList = array();
    }

    public function remove(Command $command)
    {
        // TODO: Implement remove() method.
        $key = array_search($command, $this->_commandList);
        if($key === FALSE){
            return false;
        }

        unset($this->_commandList[$key]);
        return true;
    }

    public function add(Command $command){
        return array_push($this->_commandList,$command);
    }

    public function execute()
    {
        // TODO: Implement execute() method.
        foreach($this->_commandList as $command){
            $command->execute();
        }
    }
}

class CopyCommand implements Command{
    private $_receiver;

    public function __construct(Receiver $receiver)
    {
        $this->_receiver = $receiver;
    }

    /**
     * 执行方法
     */
    public function execute()
    {
        // TODO: Implement execute() method.
        $this->_receiver->copy();
    }
}


class PasteCommand implements Command{
    private $_receiver;

    public function __construct(Receiver $receiver)
    {
        $this->_receiver = $receiver;
    }

    public function execute()
    {
        // TODO: Implement execute() method.
        $this->_receiver->paste();
    }
}
/**
 * Class Receiver
 * 接受者角色
 */
class Receiver{
    /*接收者名称*/
    private $_name;
    public function __construct($name)
    {
        $this->_name = $name;
    }


    /**
     * 复制方法
     */
    public function copy(){
        echo $this->_name, "do copy action.\n";
    }

    /**
     * 粘贴方法
     */
    public function paste(){
        echo $this->_name, "do paste action.\n";
    }

}


/**
 * 请求者角色
 */
class Invoker{
    private $_command;
    public function __construct(Command $command)
    {
        $this->_command = $command;
    }

    public function action(){
        $this->_command->execute();
    }
}

/**
 * Class Client
 * 客户端
 */
class Client{
    public static function main(){
        $receiver = new Receiver('小李');
        $pasteCommand = new PasteCommand($receiver);
        $copyCommand = new CopyCommand($receiver);

        $macroCommand = new DemoMacroCommand();
        $macroCommand->add($copyCommand);
        $macroCommand->add($pasteCommand);

        $invoker = new Invoker($macroCommand);
        $invoker->action();

        $macroCommand->remove($copyCommand);
        $invoker->action();
    }
}

Client::main();

实际上,一个命令可能需要占用单独的一个文件,这些后就需要一个类或函数负责 加载文件,判断类是否存在等。

代码如下:

<?php

class CommandContext{
    private $params = array();
    private $error = "";

    function __construct()
    {
        $this->params = $_REQUEST;
    }

    function addParam($key, $val){
        $this->params[$key] = $val;
    }

    function get($key){
        return $this->params[$key];
    }

    function setError($error){
        $this->error = $error;
    }

    function getError(){
        return $this->error;
    }

}

//简化的客户端代码
class CommandFactory{
    private static $dir = 'commands';

    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("could not find '$file");
        }

        require_once ($file);
        if( ! class_exists($class)){
            throw new CommandNotFoundException("no '$class' class located");
        }
        $cmd = new $class();
        return $cmd;

    }
}

class CommandNotFoundException extends Exception{}

class Controller {
    private $context;
    function __construct()
    {
        $this->context = new CommandContext();
    }

    /**
     * @return CommandContext
     */
    public function getContext()
    {
        return $this->context;
    }

    function process(){
        $cmd = CommandFactory::getCommand($this->context->get('action'));
        if(! $cmd->execute($this->context)){
            //处理失败
        }else {
            //成功
            //现在分发试图
            print "success";
        }
    }
}

$controller = new Controller();

$context = $controller->getContext();
//伪造用户请求
$context -> addParam('action','login');
$context -> addParam('username','bob');
$context -> addParam('pass','tiddles');
$controller -> process();

LoginCommand.php 如下:

<?php
abstract class Command{
    abstract function execute(CommandContext $context);
}

class LoginCommand extends Command{
    function execute(CommandContext $context)
    {
        // TODO: Implement execute() method.
        //$manager = Registry::getAccessManager();
        $manager = new Manager();
        $user = $context->get('username');
        $pass = $context->get('pass');
        $user_obj = $manager->login($user, $pass);
        if(is_null($user_obj)){
            $context->setError($manager->getError());
            return false;
        }
        $context->addParam("user", $user_obj);
        return true;
    }
}

//也可以把这部分内容 放到 LoginCommand中
class Manager{
    private $error;


    function login($user, $pass){
        //从数据中查找比对
        return true;
    }

    function getError(){
        return $this->error;
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值