首先看一下百度百科对策略者模式的定义:
策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
策略模式的优点有:策略模式提供了管理相关的算法族的办法、策略模式提供了可以替换继承关系的办法、使用策略模式可以避免使用多重条件转移语句。
接下来看一下策略者模式需要的组成:
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
然后举一个例子:关于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中;
如果在里面写逻辑判断就会存在‘依赖’,这个是不好的,存在很大耦合,所以把逻辑写在外部,作用就是‘注入’一个对象。
请大家参考指正