1、策略模式设计原则
第一、找出应用需要变化的部分,把他们独立出来,不要和那些不需要变化的代码混合在一起,将需要变化的部分和不需要变化的部分分别使用接口进行实现
然后将变化的接口注入到不需要变化的接口进行组合实现需求
第二、多用组合,少用继承
第三、使用接口编程
2、策略模式实现要素
第一、通过分离变化得出策略接口strategy
第二、strategy的实现类
第三、客户程序持有一个“strategy”
第四、在客户程序中选择、组合正确的strategy实现
实例展示:使用场景为鸭子产品有鸣叫和身体特征两个方法,但是他们有各自得飞行特征
鸭子抽象接口及子类:
/**
*
* 鸭子接口,有各种各样的鸭子,他们都会鸣叫,但是有些会飞行
* */
public abstract class Duck {
//鸭子的外观,由具体的子类去实现
public abstract void display();
//鸭子的鸣叫方法,父类实现公用的方式,特别的由子类重写该方法实现
public void quack(){
System.out.println("嘎嘎嘎");
}
private FlyingStrategy flyingStrategy;
public void setFlyingStrategy(FlyingStrategy flyingStrategy) {
this.flyingStrategy = flyingStrategy;
}
public void fly(){
flyingStrategy.performFly();
}
}
//大黄鸭
public class BigYellowDuck extends Duck{
public BigYellowDuck() {
// TODO Auto-generated constructor stub
super.setFlyingStrategy(new FlyNoWay());
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("我全身很黄,很大个");
}
//重写父类方法
public void quack(){
//此处也可以使用策略接口进行单独实现
System.out.println("我不会叫");
}
}
//绿脖鸭
public class GreenNeckDuck extends Duck{
public GreenNeckDuck() {
// TODO Auto-generated constructor stub
super.setFlyingStrategy(new FlyWithWin());
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("我的脖子是绿色的");
}
}
//橡胶鸭
public class OakDuck extends Duck{
public OakDuck() {
// TODO Auto-generated constructor stub
super.setFlyingStrategy(new FlyNoWay());
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("我是橡胶做的");
}
//重写父类方法
public void quack(){
System.out.println("嘎~嘎~嘎~");
}
}
//红头鸭
public class RedHeadDuck extends Duck{
public RedHeadDuck() {
// TODO Auto-generated constructor stub
super.setFlyingStrategy(new FlyWithWin());
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("我的头是红色的");
}
}
//太空鸭
public class SpaceDuck extends Duck{
public SpaceDuck() {
// TODO Auto-generated constructor stub
super.setFlyingStrategy(new FlyWithRocket());
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("我头戴宇航头盔");
}
public void quack(){
System.out.println("我通过无线电与你通信");
}
}
策略接口及实现:
//策略接口,实现飞行方式
public interface FlyingStrategy {
public void performFly();
}
//用火箭飞行
public class FlyWithRocket implements FlyingStrategy{
@Override
public void performFly() {
// TODO Auto-generated method stub
System.out.println("通过火箭飞行");
}
}
//不会飞行
public class FlyNoWay implements FlyingStrategy{
@Override
public void performFly() {
// TODO Auto-generated method stub
System.out.println("不会飞行");
}
}
//用翅膀飞行
public class FlyWithWin implements FlyingStrategy{
@Override
public void performFly() {
// TODO Auto-generated method stub
System.out.println("振翅高飞");
}
}
3、策略模式的优点
第一、使用了组合,使框架更加灵活
第二、富有弹性,可以较好的应对变化(开-闭原则)
第三、更好的代码复用性(相对于继承)
第四、消除大量的条件语句
4、策略模式的缺点
第一、客户端需要了解每个策略实现的细节
第二、增加了对象的数目
5、策略模式的适用场景
第一、许多相关的类仅仅是行为差异
第二、运行时选取不同的算法变体
第三、通过条件语句在多个分支中选取