1、策略应用者,它需要根据不同场景选用不同的策略,所以它必须拥有一个策略对象,通过调用此对象的一个方法来应用策略。
2、策略接口,为具体的不同策略提供一个统一的模板,使不同的策略对象拥有同样的类型并且对外有统一的方法名。
3、具体策略实现,实现策略接口,根据不同的场景建立不同的类。
/** *策略接口,提供统一的执行策略的方法 */ interface Strategy{ public function doAction(); } /** *策略实现一 */ class FirstStrategy implements Strategy{ public function doAction(){ return 'This is first strategy<br>'; } } /** *策略实现二 */ class SecondStrategy implements Strategy{ public function doAction(){ return 'This is second Strategy<br>'; } } /** *策略执行者 */ class StrategyCaller{ private $strategy; public function setStrategy(Strategy $strategy){ $this->strategy = $strategy; } public function doStrategy(){ echo $this->strategy->doAction(); } } $firstStrategy = new FirstStrategy(); $secondStrategy = new SecondStrategy(); $strategyCaller = new StrategyCaller(); $strategyCaller->setStrategy($firstStrategy); $strategyCaller->doStrategy(); $strategyCaller->setStrategy($secondStrategy); $strategyCaller->doStrategy();对于Strategy模式来说,主要有这些应用场景:
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户(策略调用者)隐藏具体策略(算法)的实现细节,彼此完全独立。
对于Strategy模式来说,主要有如下优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
对于Strategy模式来说,主要有如下缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。