策略模式的核心思想是:多用组合/聚合 少用继承。用行为类组合,而不是行为类继承。
策略类的缺点就是:每添加一个策略就要增加一个类,当策略过多时,类的数量也是会相应增加。
举一个例子,我们统称一类鸭子,鸭子我们分为三类,北京鸭、野鸭、玩具鸭,假定野鸭的飞行能力最强,北京鸭飞行能力差,玩具鸭不会飞。还是鸭子嘎嘎叫、游泳等特性行为。
传统的继承的实现方式如下:
抽象鸭子类
public abstract class Duck {
public Duck(){
}
public abstract void display();//现实鸭子的信息
public void quack(){
System.out.println("鸭子嘎嘎叫");
}
public void swim(){
System.out.println("鸭子会游泳");
}
public void fly(){
System.out.println("鸭子会飞");
}
}
再具体一个个实现:
public class WildDuck extends Duck{
public void display() {
System.out.println("这是野鸭");
}
}
public class PekingDuck extends Duck{
public void display() {
System.out.println("北京鸭子");
}
//北京鸭子不能飞,所以重写fly方法
public void fly(){
System.out.println("北京鸭子飞行差");
}
}
public class ToyDuck extends Duck{
public void display() {
System.out.println("玩具鸭子");
}
//玩具鸭子不具备鸭子的功能,方法都需要重写
public void quack(){
System.out.println("玩具鸭子不会嘎嘎叫");
}
public void swim(){
System.out.println("玩具鸭子不会游泳");
}
public void fly(){
System.out.println("玩具鸭子不会飞");
}
}
针对飞行这个行为,我们使用策略模式如下:
1、新建一个行为接口
public interface FlyBehavior {
void fly();//子类自己去实现
}
2、行为各有实现
public class GoodFly implements FlyBehavior{
public void fly() {
System.out.println("飞行技术很好");
}
}
public class BadFly implements FlyBehavior{
public void fly() {
System.out.println("飞行技术糟糕");
}
}
public class NoFly implements FlyBehavior{
public void fly() {
System.out.println("不会飞");
}
}
3、这时候再对具体的对象,采用组合的方式,添加行为
public class WildDuck extends Duck {
FlyBehavior flyBehavior;
//用构造器,传入 FlyBehavior 的对象
public WildDuck(){
flyBehavior = new GoodFly();
}
public void display() {
System.out.println("这是野鸭");
}
}
public class PekingDuck extends Duck {
FlyBehavior flyBehavior;
public PekingDuck(){
flyBehavior = new BadFly();
}
public void display() {
System.out.println("北京鸭子");
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
}
public class ToyDuck extends Duck {
public void display() {
System.out.println("玩具鸭子");
}
FlyBehavior flyBehavior;
public ToyDuck(){
flyBehavior = new NoFly();
}
//玩具鸭子不具备鸭子的功能,方法都需要重写
public void quack(){
System.out.println("玩具鸭子不会嘎嘎叫");
}
public void swim(){
System.out.println("玩具鸭子不会游泳");
}
}
4、写一个客户端测试下:
public class TestClient {
public static void main(String[] args) {
WildDuck wildDuck = new WildDuck();
wildDuck.flyBehavior.fly();
ToyDuck toyDuck = new ToyDuck();
toyDuck.flyBehavior.fly();
//调整需求,要求北京鸭子飞行能力是很好的
PekingDuck pekingDuck = new PekingDuck();
pekingDuck.setFlyBehavior(new GoodFly());
System.out.println("北京鸭子的实际飞行能力");
pekingDuck.flyBehavior.fly();
}
}
输出结果:
飞行技术很好
不会飞
北京鸭子的实际飞行能力
飞行技术很好
以上是对飞行这个行为进行了策略,我们还可以针对游泳这个行为进行策略。具体就不再写了。