策略模式 :定义了算法族,分别封装起来,让算法之间可以替换,此模式的让算法的变化独立于使用算法的客户。
模式精髓 :把应用中可能会变的的代码取出来,并独立封装起来,便于以后更容易的改动或者扩充此部分,而不会影响到其它部分。
实例分析:卡牌游戏中,战斗结算过程。
在在我们的项目中,对于不同的战斗类型有不同的结算方式,例如:
1)玩家之间的战斗过程中,玩家的装备有几率的摔坏,如果战斗胜利,可以抢夺对方的道具,银币。
2)玩家与世界BOSS战斗,胜利可以俘虏BOSS
3)玩家与海盗战斗的结算,可以抢夺海盗的银币
4)玩家与普通NPC战斗,会触发一个“冷却时间"机关,表示,一段时间内,玩家不会再遇到这个NPC。
5)可能后续还会开发各种战斗,会面临着各种不同的计算方法。
思考方向:考虑到战斗结算是战斗流程中最容易变化的部分,我们需要把它独立封装起来,便于以后扩充或者修改,如何封装成为了我们思考的重点,这里我们采用策略模式,把各种方法封装成类。
类关系图如下:
父类的结算函数如下:
/**
* 获取战斗结算器实例
*
* @return Model_Battle_Finisher_Abstract
*/
public function getFinisher()
{
if (! $this->_finisher) {
$class = 'Model_Battle_Finisher_' . $this->_vsType;
$this->_finisher = new $class($this);
}
return $this->_finisher;
}
回答:在面向对象的系统中,确实类都会有状态和行为属性和方法),只是在本例中,类恰好是一个行为,其实这个行为也可以有属性,比如是否结算。
设计原则: 多用组合,少用继承。组合比继承具有更好的扩展性。
面向接口编程,不要面向实现编程,在我们的项目中,我感触最深的是面向接口编程(抽象类),比如 我要做一个装备系统,我就要考虑到不同类型的装备,统一接口,而不是分别实现这些装备类。