策略设计模式(Strategy)
定义了一组算法,分别分装起来,让他们可以动态的相互替换,此模式让算法独立与使用算法的客户。
Context : 持有一个
Strategy
引用。Strategy:通常由一个抽象类或者接口来实现。给出具体的策略类所需的接口。
Concrete Strategy :包含了相关算法或者具体的行为。
示例代码
抽象策略类
/**
* 鸭子 飞 行为的接口
* @author cuishuxiang
*
*/
public interface FlyBehavior {
void fly();
}
具体角色类(实现接口)
/**
* 1,不会飞的行为
* @author cuishuxiang
*
*/
public class FlyNoWay implements FlyBehavior{
@Override
public void fly() {
//不会飞的鸭子
System.out.println("Duck can't fly!!!");
}
}
/**
* 2,用翅膀飞的鸭子
* @author cuishuxiang
*
*/
public class FlyWithWings implements FlyBehavior{
@Override
public void fly() {
System.out.println("会飞的鸭子: FlyWithWings");
}
}
具体的对象类
/**
* 鸭子 父类
* @author cuishuxiang
*
*/
public abstract class Duck {
/**
* 持有接口的引用变量
* 所有鸭子的子类,都继承他们
*/
FlyBehavior flyBehavior;
//定义一个抽象方法,让子类自己实现逻辑
public abstract void display();
public void performFly() {
//委托给行为类
flyBehavior.fly();
}
public void swim() {
//所有的鸭子 都会游泳
System.out.println("All duck can swim!");
}
public void setFlyBehavior(FlyBehavior fb) {
flyBehavior=fb;
}
}
/**
* 野鸭 继承自 父类
* @author cuishuxiang
*
*/
public class MallardDuck extends Duck{
public MallardDuck() {
/**
* 多态 , FlyWithWings 是接口的具体实现类,向上转型
*
* 该类 继承自 Duck ,故持有flyBehavior的实例变量
*/
flyBehavior=new FlyWithWings();
}
@Override
public void display() {
System.out.println("我是正宗的:MallardDuck");
}
}
Client测试类:
/**
* 测试类
* @author cuishuxiang
*
*/
public class DuckTest {
public static void main(String[] args) {
Duck mallardDuck=new MallardDuck();
mallardDuck.performFly();
//设定不会飞 动态改变其行为
mallardDuck.setFlyBehavior(new FlyNoWay());
mallardDuck.performFly();
mallardDuck.display();
}
}
打印结果为:
会飞的鸭子: FlyWithWings
Duck can't fly!!!
我是正宗的:MallardDuck
以上的小例子,源自 Head First设计模式;
个人理解:策略模式,就是封装了一些 行为(算法)比如上例中的fly()的行为
,创建不同的类去实现该fly()
行为。
在具体的角色中,持有一个该行为的引用 例如上例中的:FlyBehavior flyBehavior
,使用 java 多态,向上转型
将具体的实现类FlyWithWings
变为声明的 FlyBehavior
,调用其方法,从而达到动态变化。
策略模式的优缺点
优点
扩展性好。增加一个strategy的时候,只需要实现接口,增加具体的逻辑,不需要的时候,就可以删除。如:上面例子中 ,通过实现
FlyBehavior
增加策略。良好的封装。策略模式的入口在Context类中(上例中的
Duck
),使用者 ,需要那种策略就传入那种策略(如:public void setFlyBehavior(FlyBehavior fb)
),避免了很多的if - else判断
缺点
- 用户必须知道有那几种策略(如上例:
FlyNoWay
,FlyWithWings
),来决定使用那种策略。 - 如果策略的数量比较多的话,会增加很多的类。