本文要点:
- 定义
- 设计原则一:封装变换部分
- 设计原则二:针对接口编程,而不是针对实现编程。
- 设计原则三:多用组合,少用继承。
- 实例:鸭子与行为
策略模式(Strategy Pattern)
一、定义
策略模式定义了算法组,分别封装起来,让他们之间可以相互替换。此模式让算法族的变换独立于使用该算法的客户。
二、设计原则一:封装变换部分
找出可能变换的部分,将其独立,使得某些部分的变化不会影响到其他部分。将这些变换的部分(例如行为)分离出来,组成一类。
三、设计原则二:针对接口编程,而不是针对实现编程。
用行为类去实现行为接口,而不是具体子类去实现行为接口。
针对接口编程本质是针对超类编程。
关键在于利用多态
,可以对超类编程,在执行时根据具体情况执行行为。
四、实例:鸭子类和行为类
1. 鸭子类
Duke抽象父类,所有的鸭子继承自父类,在子类里面实现具体特性,并且设置行为。
public abstract class Duke {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void setFly(FlyBehavior fly) {
flyBehavior = fly;
}
public void setQuack(QuackBehavior quack) {
quackBehavior = quack;
}
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
public abstract String getDescription();
}
//黑色鸭子(用翅膀飞,会叫)
public class BlackDuck extends Duke{
String color = "black";
public BlackDuck() {
flyBehavior = new FlyWithWings();
quackBehavior = new QuackCry();
}
public String getDescription() {
return color+" "+flyBehavior.getDescription()+" "+quackBehavior.getDescription();
}
}
//木头鸭子(不会飞,吱吱叫)
public class WoodDuck extends Duke{
String color = "yellow";
public WoodDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new QuackZhiZhi();
}
public String getDescription() {
return color+" "+flyBehavior.getDescription()+" "+quackBehavior.getDescription();
}
}
2.飞行类(行为类-定义中的算法族)
//飞行接口
public interface FlyBehavior {
public String getDescription();
public void fly();
}
//具体飞行行为类:不会飞
public class FlyNoWay implements FlyBehavior{
public String getDescription() {
return "fly no way";
}
public void fly() {
System.out.println(getDescription());
}
}
//用翅膀飞
public class FlyWithWings implements FlyBehavior{
public String getDescription() {
return "fly with wings";
}
public void fly() {
System.out.println(getDescription());
}
}
3.鸭叫类
//鸭叫接口
public interface QuackBehavior {
public String getDescription();
public void quack();
}
//正常鸭叫
public class QuackCry implements QuackBehavior{
public String getDescription() {
return "quack cry";
}
public void quack() {
System.out.println(getDescription());
}
}
//吱吱叫
public class QuackZhiZhi implements QuackBehavior{
public String getDescription() {
return "quack zhizhi";
}
public void quack() {
System.out.println(getDescription());
}
}
4.测试
public class testDuck {
public static void main(String[] args) {
Duke duke = new BlackDuck();
System.out.println(duke.getDescription());
duke.performFly();//飞行
duke.performQuack();//鸭叫
duke = new WoodDuck();
System.out.println(duke.getDescription());
duke.performFly();
duke.performQuack();
}
}
执行代码:结果正确
black fly with wings quack cry
fly with wings
quack cry
yellow fly no way quack zhizhi
fly no way
quack zhizhi
5.扩展新的行为
我们上面实现了策略模式,现在来扩展行为体会一下策略模式的便捷。这里扩展一个火箭推进的行为FlyRocketPowered()
,实现`FlyBehavior接口:
public class FlyRocketPowered implements FlyBehavior{
public String getDescription() {
return "fly with Rocket Power!!!";
}
public void fly() {
System.out.println(getDescription());
}
}
给木鸭子改装火箭推进装置:
Duke duke = new WoodDuck();
System.out.println(duke.getDescription());
duke.performFly();
duke.performQuack();
duke.setFly(new FlyRocketPowered());//给木鸭子火箭推进器
duke.performFly();
结果:
yellow fly no way quack zhizhi
fly no way
quack zhizhi
fly with Rocket Power!!!
成功的更改为火箭推荐!很方便吧!这就是策略模式更换算法族(本例中是行为类)的特点,便于扩展。
五、设计原则三:多用组合,少用继承。
1.什么是组合
像实例中将两个类组合起来用,这就是组合(Composition)。这种方法和“继承”的区别在于,鸭子的行为不是继承而来,而是和适当的行为对象组合而来的。
2.组合的优点
可复用、可扩展、可维护
3.继承提供行为的缺点
- 代码在多个子类中重复
- 运行时行为不容易改变
- 难以知道所有行为
- 牵一发而动全身,造成其他子类不想要的改变。