深入php面向对象、模式与实践(4)

问题: 在一个军队中,有很多军队,军队下面可能包含军队/步兵/弓箭手,这时我们要显示一个军队的战斗力/需要粮食的各级分配?(遍历对象并设置显示方法).怎么办?.解决办法是军队还是保存自己的基本信息,设置一个访问者,访问者包含总战斗力方法和总粮食的方法.

访问者模式

访问者

abstract class 军队访问者{ abstract function 访问(单元); function 访问军队($军队){ $this->访问($军队); } function 访问弓箭手($弓箭手){ $this->访问($弓箭手); } //这里重复定义了大量代码,其实可以用call来替代 function __call($method_name,$args){ if(strrpos($method_name, "访问")){ return call_user_func_array( array($this,"访问"),$args ); } } } class 军队战斗力访问者 extends 军队访问者{ private $text=""; function 访问($单元){ $ret = ""; $pad = 4*$单元->getDpth(); //设置显示深一级前面多4个空格. $ret .= sprintf( "%{$pad}s",""); $ret .= get_class($单元). ": "; $ret .= "战斗力: " .$单元->bombardStrenth()."\n"; $this->text .=$ret; } function get_text(){ return $this->text; } }

被访问者

abstract class 单元{ function 接受($军队访问者){ $method = "访问_".get_class($this); $军队访问者->$method($this); } private $depth; protected function set_depath($depth){ $this->depth=$depth; } function get_depth(){ return $this->depth; } ... } abstract class 综合单元 extends 单元{ function 接受($军队访问者){ parent::接受($军队访问者) foreach($this->单元集合 as $this_unit){ $this->unit->接受($军队访问者); } } } class 军队 extends 综合单元{ function bombardStrenth(){ $ret =0; foreach($this-units() as $unit){ $ret += $unit->bombardStrenth(); } return $ret } } class 弓箭手 extends 单元{ function bombardStrenth(){ return 4; } }

调用

$main_army = new Army(); $main_army->add_unit(new 步兵()); $main_army->add_unit(new 弓箭手()); $军队战斗力访问者_实例 =new 军队战斗力访问者(); $main_army->接受(均分战斗力访问者); print $军队战斗力访问者->get_text();

输出

复制代码 代码如下:


军队: 战斗力: 50
    步兵: 攻击力 :48
    弓箭手: 攻击力: 4

5.4 命令模式

例子为Web页面的login和feed_back,假如都需要使用ajax提交,那么问题来了,将表单封装好提交上去,得到了返回结果.如何根据返回结果跳转不同的页面?.

有些同学就说了,login和feed_back各自写一个方法憋,提交的时候调用各自的方法.

然后再来个logout命令..增加..删除..命令怎么办..

命令模式比较适合命令执行例如登陆,反馈等简单只需要判断是否成功的任务

命令模式

命令:

abstract class Command{ abstract function execute(Conmmand_Context $context); } class Login_Command extends Command{ function execute(CommandContext $context){ $managr =Register::getAccessManager(); $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; } }

部署命令的调用者

class Command_Facotry{ public function get_command($action){ $class = UCFirst(strtolower($action))."_Command"; $cmd = new $class(); return $cmd; } }

客户端

class Controller{ private $context; function __construct(){ //Command_Context主要用来存储request和params $this->context =new Command_Context(); } function process(){ $cmd Command_Factory::get_commad($this->context->get('action')); if(!$cmd-execute($this->context)){ //错误处理 }else{ //成功 分发视图 } } }

使用

$controller =new Controller(); $context = $controller->get_context(); $context->add_param('action','login'); $context->add_param('username','404_k'); $context->add_param('pass','123456'); $controller->process();

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgwyjz.html