一句话概述:
Strategy(策略):定义一系列算法,把他们一个个封装起来,并且使他们可互相替换。本模式使算法可变化可独立于使用他的用户。同样也是使用组合模式,但是状态是封装了实体类的所有操作,而策略只是改变了他具体行事的某一个或几个方法。策略的意图在于算法的封装与动态改变。
策略模式可以解决什么样的问题?
实例:模拟鸭子
定义一个父类Duck
public abstract class Duck {
public void Quack() {
System.out.println("~~gaga~~");
}
public abstract void display();
public void swim() {
System.out.println("~~im swim~~");
}
}
然后GreenHeadDuck继承Duck
public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("**GreenHead**");
}
}
同理有其他red,yellow等鸭子。
所有鸭子的Quack和swim方法都相同,只有display不同,所以使用抽象类,不同的子类继承时对其进行不同的实现。
已上是普通的OO思维。
此时,需求需要添加一个会飞的鸭子,理论上也可以和display一样添加一个抽象方法,不同的子类根据实际情况进行实现。
由于是父类添加的抽象类,那么已经继承的子类每个都需要对这个方法重写,工作量太大。
用策略模式来新需求解决
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?叫声、飞行
重新设计超类Duck
public abstract class Duck {
FlyBehavior flyBehavior;
//动态设置飞行行为
public void setFlyBehavior (FlyBehavior fb) {
flyBehavior = fb;
}
//将飞行行为委托给飞行行为类处理
public void performFly() {
flyBehavior.fly();
}
public void Quack() {
System.out.println("~~gaga~~");
}
public abstract void display();
public void swim() {
System.out.println("~~im swim~~");
}
}
创建一个飞行接口:
public interface FlyBehavior {
public void fly();
}
接口的实现:
//用翅膀飞
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("I'm flying!!");
}
}
//火箭推射器飞
public class FlyRocketPowered implements FlyBehavior {
public void fly() {
System.out.println("I'm flying with a rocket");
}
}
接下来就可以灵活的新建出要相应功能的鸭子啦。
普通鸭
//普通鸭子
public class PTDuck extends Duck {
public PTDuck () {
flyBehavior = new FlyWithWings();//动态设置想要的飞行功能,例如用翅膀飞
}
public void display() {
System.out.println("I'm a real Red Headed duck");
}
}
火箭鸭
//火箭鸭
public class PTDuck extends Duck {
public PTDuck () {
flyBehavior = new FlyRocketPowered ();//动态设置想要的飞行功能,例如用火箭飞hhhh
}
public void display() {
System.out.println("I'm a real Red Headed duck");
}
}
如果现在需要新建一个不会飞的功能,只需要创建一个类继承飞行功能的接口。
相应的鸭子只需要在构造方法里新建一个flyBehavior 传到父类。