- 分别分装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象,原则就是: 分离变化部分,封装接口,基于接口编程各种功能。 此模式让行为算法的变化独立于算法的使用者。
- 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。主要解决的是在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
- 关键在于多个不同的行为实现同一个接口;
- 优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
- 缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
如果一个系统的策略有多个,就需要考虑使用混合模式,解决策略类膨胀的问题。
这个案例模拟的是各种鸭子以及他们的行为,比如有红头鸭,绿头鸭,他们各自都有不同的行为,比如红头鸭飞的不好,会”GeGe”叫,而绿头鸭飞的好,会”GaGa”叫,使用策略模式实现下面的功能;
其中Duck类是超类,下面有子类红头鸭和绿头鸭,而每个行为都成为一个接口,并且相应的有实现类,这些实现类就是算法族。看类结构
首先鸭子包:
Duck类
package strategy.duck;
import strategy.fly.FlyBehavior;
import strategy.quack.QuackBehavior;
/**
* 鸭子的超类
*/
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public void fly(){
flyBehavior.fly();
}
public void quack(){
quackBehavior.quack();
}
public abstract void display(); //抽象方法,子类必须实现
public void swim(){//父类的方法 公用
System.out.println("I'm Swim");
}
//动态的改变 setter方法
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
红头鸭的类:
package strategy.duck;
import strategy.fly.BadFlyBehavior;
import strategy.quack.GeGeQuackBehavior;
public class RedHeadDuck extends Duck{
public RedHeadDuck() {
flyBehavior = new BadFlyBehavior(); //飞的不好
quackBehavior = new GeGeQuackBehavior(); //会GeGe叫
}
@Override
public void display() {
System.out.println("-----------I'm a Red Duck--------");
}
}
绿头鸭的类:
package strategy.duck;
import strategy.fly.GoodFlyBehavior;
import strategy.quack.GaGaQuackBehavior;
public class GreenHeadDuck extends Duck{
public GreenHeadDuck() {
flyBehavior = new GoodFlyBehavior(); //飞的好
quackBehavior = new GaGaQuackBehavior(); //会GaGa叫
}
//抽象方法
@Override
public void display() {
System.out.println("----------I'm a Green Duck------");
}
}
然后再看fly包:
首先有一个fly接口
package strategy.fly;
public interface FlyBehavior {
void fly();
}
具体的三个实现类:
package strategy.fly;
public class BadFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("Bad Fly");
}
}
package strategy.fly;
public class GoodFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("Good Fly");
}
}
package strategy.fly;
public class NoFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("No Fly");
}
}
再看quack包:
首先一个接口:
package strategy.quack;
public interface QuackBehavior {
void quack();
}
然后看三个具体的实现类:
package strategy.quack;
public class GaGaQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("GaGa");
}
}
package strategy.quack;
public class GeGeQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("GeGe");
}
}
package strategy.quack;
public class NoQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("No Quack");
}
}
再看具体的测试类:
package strategy.test;
import strategy.duck.Duck;
import strategy.duck.GreenHeadDuck;
import strategy.duck.RedHeadDuck;
import strategy.fly.NoFlyBehavior;
import strategy.quack.NoQuackBehavior;
public class MyTest {
public static void main(String[] args) {
Duck green = new GreenHeadDuck();
Duck red = new RedHeadDuck();
green.display() ;//必须实现的
green.fly();
green.quack();
green.swim(); //都会的
red.display();
red.fly();
red.quack();
red.swim();
//动态设置红头鸭
red.setFlyBehavior(new NoFlyBehavior()); //不会飞
red.setQuackBehavior(new NoQuackBehavior());//不会叫
red.display();
red.fly();
red.quack();
red.swim();
}
}
再看一个更简单的例子:实现加减乘一系列操作;
先看一个定义活动的 Strategy 接口
package strategy.partice;
/**
* 接口
*/
public interface Strategy {
public int doOperation(int num1, int num2);
}
以及实现它的三个实现类:
package strategy.partice;
/**
* 算法1: 实现加法
*/
public class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
package strategy.partice;
/**
* 算法2:实现减法
*/
public class OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
package strategy.partice;
/**
* 算法3: 实现乘法
*/
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
然后再看实现了 Strategy 接口的实体策略类,Context 是一个使用了某种策略的类。
package strategy.partice;
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
测试:
package strategy.partice;
public class MyTest {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
运行结果
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50