策略模式(strategy pattern)

策略模式定义:

定义了算法族,分别封装起来,让他们之间可以相互替换,
此模式让算法分变化独立于使用算法的客户。

设计原则:

  1. 找出应用中可能需要变化之处,并把他们独立出来

    把会变化的部分取出来并封装起来,以便以后可以轻易的改变或扩充此部分,
    而不影响不需要变化的部分。
    
    系统中某部分改变不会影响其他部分。
    系统间模块的解耦。
    
  2. 针对接口编程,而不是针对实现编程

    接口代表每个行为,而行为的每个实现都将实现其中的一个接口。
    针对接口编程,关键就在多态,
    利用多态程序可以针对超类型编程,
    执行时会根据实际情况执行到真正的行为,
    
  3. 多用组合,少用继承

    使用组合建立系统具有很大的弹性,不仅将算法族分装成类,
    更可以在运行时动态的改变行为,
    只要组合的行为对象符合正确的接口标准即可。
    

适用性
许多相关的类仅仅是行为有异,策略提供了一种用多个行为中的一个行为来配置一个类的方法。

优点:
1)提供了可以替换继承关系的办法,可以将算法族独立于角色类。
2)角色类可以动态的选择行为的不同实现

缺点
1)产生多个策略类
2)角色类需要知道具体的策略类

思考(应用场景)
1)商品的优惠活动
算法族:定义活动优惠的接口,不同的优惠活动实现这个接口
角色类:购物车(根据具体活动和算法族的映射, 得到具体类)
2) 根据不同区域计算运费

代码实现



/*
 * 飞行算法族
 */
interface FlyBehavior {
	public function fly();
}


class FlyWithWings  implements FlyBehavior {
	public function fly() {
		echo "Fly with wings \n";
	}
}

class FlyNoWay  implements FlyBehavior {
	public function fly() {
		echo "Fly no way \n";
	}
}


/*
 * 叫声算法族
 */
interface QuackBehavior {
	public function quack();
}


class Quack implements QuackBehavior {
	public function quack(){
		echo "Quack \n";
	}
}


class Squeak implements QuackBehavior {
	public function quack(){
		echo "Squeak \n";
	}
}



/*
 *  角色类
 */
class Duck {

	private $flyBehavior;
	private $quackBehavior;

	public function __construct(FlyBehavior $flyBehavior, QuackBehavior $quackBehavior){
		$this->flyBehavior = $flyBehavior;
		$this->quackBehavior = $quackBehavior;
	}


	public function fly(){
		$this->flyBehavior->fly();
	}


	public function quack(){
		$this->quackBehavior->quack();
	}

}


/*
 * 测试代码
 * 改进:可以通过容器解决依赖,避免new的使用
 */
$flyWithWings = new FlyWithWings();
$squeak = new Squeak();
$duck = new Duck($flyWithWings, $squeak);

$duck->fly();
$duck->quack();


运行结果

$ php test.php 
Fly with wings 
Squeak 

相关概念引用了 《Head First 设计模式》

你可能感兴趣的:(设计模式)