php设计模式之状态模式实例分析【星际争霸游戏案例】
本文实例讲述了php设计模式之状态模式,分享给大家供大家参考,具体如下:
星际的一些兵种会有不止一种状态,比如坦克可以架起来,机枪兵可以打兴奋剂,甚至还有一些被动的,比如被虫族女王喷洒绿色液体后,敌人的行动变慢。
如果按照一般的思路,每次我们对一个小兵进行操作的时候,比如一辆坦克,我们都要用if判断他的状态,这样代码中会有很多的if,else或者swith。
不过我们可以发现,我们需要的是他在某个状态下的行为,如果把这些行为按照状态封装起来,就可以减少大量的判断。
待解决的问题:封装坦克的状态,让状态自己去控制行为。
思路:把状态作为属性,兵种类本身只控制状态的变化,具体的行为由状态类定义。
状态(State)模式示例:
- <?php
- //坦克状态的接口
- interface TankState
- {
- //坦克的攻击方法
- public function attack();
- }
- //坦克普通状态
- class TankState_Tank implements TankState
- {
- //坦克的攻击方法
- public function attack()
- {
- //这里简单的输出当前状态
- echo "普通状态";
- }
- }
- //坦克架起来的状态
- class TankState_Siege implements TankState
- {
- //坦克的攻击方法
- public function attack()
- {
- //这里简单的输出当前状态
- echo "架起来了";
- }
- }
- //坦克类
- class Tank
- {
- //状态
- public $state;
- //坦克的攻击方法
- public function __construct()
- {
- //新造出来的坦克当然是普通状态
- $this->state = new TankState_Tank();
- }
- //设置状态的方法,假设参数为玩家点击的键盘
- public function setState($key)
- {
- //如果按了s
- if($key = 's')
- {
- $this->state = new TankState_Siege();
- }
- //如果按了t
- elseif($key = 't')
- {
- $this->state = new TankState_Tank();
- }
- }
- //坦克的攻击方法
- public function attack()
- {
- //由当前状态自己来处理攻击
- $this->state->attack();
- }
- }
- //新造一辆坦克
- $tank = new Tank();
- //假设正好有个敌人路过,坦克就以普通模式攻击了
- $tank->attack();
- //架起坦克
- $tank->setState('s');
- //坦克再次攻击,这次是架起模式
- $tank->attack();
- ?>
用途总结:状态模式可以将和状态相关的行为和属性封装,除了切换状态时,其它地方就不需要大量的判断当前状态,只要调用当前状态的方法等。
实现总结:用一个接口规范状态类需要实现的方法,比如上面的TankState规定了attack()。把各个状态封装成类,将不同状态下的不同方法放入各自的状态类,比如上面的攻击方法,同时所有的状态执行接口。原来的事务类,比如上面的Tank类,只负责状态切换,一旦需要某一个方法的调用,只要交给当前状态就可以了。