php设计模式之状态模式实例分析【星际争霸游戏案例】

本文实例讲述了php设计模式之状态模式,分享给大家供大家参考,具体如下:

星际的一些兵种会有不止一种状态,比如坦克可以架起来,机枪兵可以打兴奋剂,甚至还有一些被动的,比如被虫族女王喷洒绿色液体后,敌人的行动变慢。

如果按照一般的思路,每次我们对一个小兵进行操作的时候,比如一辆坦克,我们都要用if判断他的状态,这样代码中会有很多的if,else或者swith。

不过我们可以发现,我们需要的是他在某个状态下的行为,如果把这些行为按照状态封装起来,就可以减少大量的判断。

待解决的问题:封装坦克的状态,让状态自己去控制行为。

思路:把状态作为属性,兵种类本身只控制状态的变化,具体的行为由状态类定义。

状态(State)模式示例:

  1. <?php
  2. //坦克状态的接口
  3. interface TankState
  4. {
  5. //坦克的攻击方法
  6. public function attack();
  7. }
  8. //坦克普通状态
  9. class TankState_Tank implements TankState
  10. {
  11. //坦克的攻击方法
  12. public function attack()
  13. {
  14. //这里简单的输出当前状态
  15. echo "普通状态";
  16. }
  17. }
  18. //坦克架起来的状态
  19. class TankState_Siege implements TankState
  20. {
  21. //坦克的攻击方法
  22. public function attack()
  23. {
  24. //这里简单的输出当前状态
  25. echo "架起来了";
  26. }
  27. }
  28. //坦克类
  29. class Tank
  30. {
  31. //状态
  32. public $state;
  33. //坦克的攻击方法
  34. public function __construct()
  35. {
  36. //新造出来的坦克当然是普通状态
  37. $this->state = new TankState_Tank();
  38. }
  39. //设置状态的方法,假设参数为玩家点击的键盘
  40. public function setState($key)
  41. {
  42. //如果按了s
  43. if($key = 's')
  44. {
  45. $this->state = new TankState_Siege();
  46. }
  47. //如果按了t
  48. elseif($key = 't')
  49. {
  50. $this->state = new TankState_Tank();
  51. }
  52. }
  53. //坦克的攻击方法
  54. public function attack()
  55. {
  56. //由当前状态自己来处理攻击
  57. $this->state->attack();
  58. }
  59. }
  60. //新造一辆坦克
  61. $tank = new Tank();
  62. //假设正好有个敌人路过,坦克就以普通模式攻击了
  63. $tank->attack();
  64. //架起坦克
  65. $tank->setState('s');
  66. //坦克再次攻击,这次是架起模式
  67. $tank->attack();
  68. ?>

用途总结:状态模式可以将和状态相关的行为和属性封装,除了切换状态时,其它地方就不需要大量的判断当前状态,只要调用当前状态的方法等。

实现总结:用一个接口规范状态类需要实现的方法,比如上面的TankState规定了attack()。把各个状态封装成类,将不同状态下的不同方法放入各自的状态类,比如上面的攻击方法,同时所有的状态执行接口。原来的事务类,比如上面的Tank类,只负责状态切换,一旦需要某一个方法的调用,只要交给当前状态就可以了。