首先看一下百度百科对策略者模式的定义:
策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
策略模式的优点有:策略模式提供了管理相关的算法族的办法、策略模式提供了可以替换继承关系的办法、使用策略模式可以避免使用多重条件转移语句。
接下来看一下策略者模式需要的组成:
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
然后举一个例子:关于dota玩家在游戏中被杀后的情绪:画面比较美
素质最好的可能会说:技不如人,甘拜下风;
素质比较好的可能会称赞对方;
素质比较差的可能就会关进小黑屋了。。。
<?php
class dotar
{
public function say()
{
if(isset($_GET['best'])){
echo "技不如人,甘拜下风";
}else{
echo "真是日狗了";
}
}
}
$miQi = new dotar();
$miQi->say();
这个简单的代码大家都明白,现在要是多了一个素质极其差的玩家,又多了一个神经病玩家,我们就要ifelse,这样硬编码的方式不太好。
此时可以用策略者模式:
<?php
// 抽象策略角色 策略类,通常由一个接口或者抽象类实现
interface dotar
{
public function say();
}
// 具体策略角色 包装了相关的算法和行为
class bestDotar implements dotar
{
public function say()
{
echo "技不如人,甘拜下风";
}
}
// 具体策略角色 包装了相关的算法和行为
class betterDotar implements dotar
{
public function say()
{
echo "大侄子,这波操作可以";
}
}
// 具体策略角色 包装了相关的算法和行为
class badDotar implements dotar
{
public function say()
{
echo "日了狗了,我要...你...";
}
}
class test
{
protected $hero;
public function index()
{
$this->hero->say();
}
// 环境角色 持有一个策略类的引用,最终给客户端调用
public function role(dotar $heros)
{
$this->hero = $heros;
}
}
$test1 = new test();
if(isset($_GET['better'])){
$heros = new betterDotar();
}elseif(isset($_GET['best'])){
$heros = new bestDotar();
}else{
$heros = new badDotar();
}
$test1->role($heros);
$test1->index();
大家可能会觉得,这不就是把ifelse写在外面了吗?
不是只将if else移动到外面,这是一种思想,处理某一个策略使用一个类来处理,而不是将一堆逻辑写到一个action中;
如果在里面写逻辑判断就会存在‘依赖’,这个是不好的,存在很大耦合,所以把逻辑写在外部,作用就是‘注入’一个对象。
请大家参考指正