策略模式属于Java 23种设计模式中行为模式之一,那先看看什么是策略模式。
策略模式的定义:
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
其实我们在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等。或者比如网购,你可以选择工商银行、农业银行、建设银行等等,但是它们提供的算法都是一致的,就是帮你付款。
在软件开发中也会遇到相似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。(这个在下面案例中详讲)
优点:
缺点:
现在有三只鸭子: 绿毛鸭、红毛鸭、小鸭子(小鸭子还不会飞)
现在定义一个鸭子的父类:
里面有都会叫的方法,有显示外观的方法(因为每只都不一样,就需要子类重写)
还会飞行 (这里使用策略模式)
public abstract class duck {
//鸭子都会叫:
public void quack(){
System.out.println("嘎嘎嘎");
}
//鸭子的外观,因为都不一样,所以由子类去实现
public abstract void display();
//以下使用策略模式:
//在父类中持有该接口,并由该接口代替飞行行为(组合)
private Flying flying;
//提供set方法
public void setFlying(Flying flying) {
this.flying = flying;
}
public void fly(){
flying.Fly();
}
}
定义一个飞行接口:
/**
* 策略接口:实现了鸭子的飞行行为
*/
public interface Flying {
void Fly();
}
我们知道策略模式就是把需要用的算法封装起来,就在另一个包内封装了会飞和不会飞的两个方法:
会飞(继承至上面的飞行接口,重写飞行方法):
public class FlyWithWin implements Flying {
@Override
public void Fly() {
System.out.println("我会飞");
}
}
不会飞:
public class FlyNoWay implements Flying {
@Override
public void Fly() {
System.out.println("我不会飞行");
}
}
注意: 上面这两个方法我是把他们单独封装起来,当做算法族,然后程序需要使用里面某个算法的时候,程序不会受算法改变的影响,因为这里面的算法最终效果是一致的
红毛鸭类:
/**
* 红色鸭子
*/
public class RedDuck extends duck{
public RedDuck(){
super();
//给鸭子注入飞行的能力,这里就是通过算法族里面的会飞的算法
super.setFlying(new FlyWithWin());
}
@Override
public void display() {
System.out.println("我是红色的鸭子");
}
}
绿毛鸭:
/**
*
* 绿色鸭子
*/
public class GreenDuck extends duck{
public GreenDuck(){
super();
//给鸭子注入飞行的能力,这里也是通过算法族里面的会飞的算法
super.setFlying(new FlyWithWin());
}
@Override
public void display() {
System.out.println("我是绿色的鸭子");
}
}
小鸭子类(不会飞):
/**
* 小鸭子,还不会飞
*/
public class SamllDuck extends duck{
public SamllDuck(){
super();
//小鸭子不会飞,所以使用了算法族里面不会飞的算法
super.setFlying(new FlyNoWay());
}
@Override
public void display() {
System.out.println("我还是小鸭子");
}
//因为小鸭子和大鸭子的叫声不一样,所以重写叫声方法
public void quack(){
System.out.println("嘎~嘎~嘎");
}
}
测试类:
public class Test {
public static void main(String[] args) {
System.out.println("***测试鸭子程序***");
duck d = null;
//这下面是轮流运行!!!!
d = new RedDuck(); //测试红色的鸭子
d = new GreenDuck(); //测试绿色的鸭子
d = new SamllDuck(); //测试小鸭子
d.display();
d.quack();
d.fly();
System.out.println("***测试完毕***");
}
}
当使用红毛鸭为对象时:
***测试鸭子程序***
我是红色的鸭子
嘎嘎嘎
我会飞
***测试完毕***
当使用绿毛鸭为对象时:
***测试鸭子程序***
我是绿色的鸭子
嘎嘎嘎
我会飞
***测试完毕***
当使用小鸭子为对象时:
***测试鸭子程序***
我还是小鸭子
嘎~嘎~嘎
我不会飞行
***测试完毕***