今天我们就来学习一下23种设计模式中的策略模式。如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
概念:
策略模式是定义了一系列的算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
特点:
优点:
- 算法可以自由切换。
- 避免使用多重条件判断。
- 扩展性良好。
缺点:
- 策略类会增多。
- 所有策略类都需要对外暴露。
代码:
鸭子飞翔行为的接口
package cn.ppdxzz.strategy;
/**
* description:鸭子飞翔行为的接口
* @author: PeiChen JavaAnything
*/
public interface FlyBehavior {
/**
* 会飞的行为,子类具体实现
*/
void fly();
}
飞翔技术好
package cn.ppdxzz.strategy;
/**
* description:飞翔技术好
* @author: PeiChen JavaAnything
*/
public class GoodFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("飞翔技术高超...");
}
}
飞翔技术一般
package cn.ppdxzz.strategy;
/**
* description:飞翔技术一般
* @author: PeiChen JavaAnything
*/
public class BadFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("飞翔技术一般...");
}
}
不会飞翔
package cn.ppdxzz.strategy;
/**
* description:不会飞翔
* @author: PeiChen JavaAnything
*/
public class NoFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("不会飞翔...");
}
}
嘎嘎叫的行为
package cn.ppdxzz.strategy;
/**
* description:嘎嘎叫的行为
* @author: PeiChen JavaAnything
*/
public interface QuackBehavior {
/**
* 嘎嘎叫
*/
void quack();
}
抽象鸭子类
package cn.ppdxzz.strategy;
/**
* description:抽象鸭子类
* @author: PeiChen JavaAnything
*/
public abstract class Duck {
/**
* 属性,策略接口
*/
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
/**
* 显示鸭子信息
*/
public abstract void display();
public void quack() {
System.out.println("鸭子嘎嘎叫...");
}
public void swim() {
System.out.println("鸭子会游泳...");
}
public void fly() {
//改进方法
if (flyBehavior != null) {
flyBehavior.fly();
}
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
北京鸭
package cn.ppdxzz.strategy;
/**
* description:北京鸭
* @author: PeiChen JavaAnything
*/
public class PekingDuck extends Duck {
public PekingDuck() {
//飞翔技术一般的北京鸭
flyBehavior = new BadFlyBehavior();
}
@Override
public void display() {
System.out.println("---北京鸭---");
}
}
玩具鸭
package cn.ppdxzz.strategy;
/**
* description:玩具鸭
* @author: PeiChen JavaAnything
*/
public class ToyDuck extends Duck {
public ToyDuck() {
//不会飞的玩具鸭
flyBehavior = new NoFlyBehavior();
}
@Override
public void display() {
System.out.println("---玩具鸭---");
}
@Override
public void quack() {
System.out.println("玩具鸭不会叫...");
}
@Override
public void swim() {
System.out.println("玩具鸭不会游泳...");
}
}
野鸭
package cn.ppdxzz.strategy;
/**
* description:野鸭
* @author: PeiChen JavaAnything
*/
public class WildDuck extends Duck {
public WildDuck() {
//飞翔技术好的野鸭
flyBehavior = new GoodFlyBehavior();
}
@Override
public void display() {
System.out.println("---野鸭---");
}
}
策略模式客户端
package cn.ppdxzz.strategy;
/**
* description:策略模式客户端
* @author: PeiChen JavaAnything
*/
public class Client {
public static void main(String[] args) {
System.out.print("北京鸭:");
PekingDuck pekingDuck = new PekingDuck();
pekingDuck.fly();
System.out.print("玩具鸭:");
ToyDuck toyDuck = new ToyDuck();
toyDuck.fly();
System.out.print("野鸭:");
WildDuck wildDuck = new WildDuck();
wildDuck.fly();
System.out.print("更改飞行能力的北京鸭:");
//动态的更改北京鸭的飞行状态
pekingDuck.setFlyBehavior(new NoFlyBehavior());
pekingDuck.fly();
}
}
运行结果:
总结:
- 策略模式的核心思想是多用组合/聚合少用继承,用行为类组合,而不是行为的继承。
- 策略模式需要注意的是每添加一个策略就要增加一个类,当策略过多时会导致类的数目庞大。