策略模式也叫政策模式,是一种比较简单的设计模式。它的目的是定义一组算法,将每个算法都封装起来。并且使他们之间可以互换。针对一组算法,将每一个算法封装到具有接口的独立的类中,从而使他们可以相互替换,使得算法可以在不影响到客户端的情况下发生变化。
引入
我们先来看一个示例
// 定义一个抽象类
public abstract class Duck {
public Duck(){}
/**
* 显示鸭子信息
*/
public abstract void display();
public void quack() {
System.out.println("鸭字嘎嘎叫~");
}
public void swim(){
System.out.println("dack can swim");
}
public void fly(){
System.out.println("dack can fly");
}
}
// 定义北京鸦
public class PekingDuck extends Duck{
@Override
public void display() {
System.out.println("Pecking Duck");
}
/**
* 因为北京鸦不能飞翔,所以重写fly方法
*/
@Override
public void fly() {
System.out.println("Peking Duck can not fly");
}
}
//定义玩具鸦
public class ToyDock extends Duck{
@Override
public void display() {
System.out.println("Tony Duck");
}
// 玩具鸦不会叫,不会飞,不会游泳。
// 所以要重写父类所有方法
@Override
public void quack() {
System.out.println("Tony DUck can not quack");
}
@Override
public void swim() {
System.out.println("Tony Duck can not swim");
}
@Override
public void fly() {
System.out.println("Tony Duck can not fly");
}
}
可以看到,北京鸭和玩具鸦都继承了Duck类,所以fly让所有子类都会飞了,这是不正确的。当然,我么可以通过重写方法来解决,但是一个玩具鸦,我们需要重写父类所有的方法的实现,为了解决这种问题,我们使用策略模式。
我们就只写fly这一个功能吧。
/**
* 定义一个行为接口
*/
public interface FlyBehavior {
void fly();
}
// 实现这个接口
public class GoodFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("飞翔技术高超");
}
}
public class BadFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("飞翔技术一般");
}
}
public class NoFlyBehavior implements FlyBehavior{
@Override
public void fly() {
System.out.println("不会飞翔");
}
}
// 定义一个抽象类
public abstract class Duck {
/**
* 属性,策略接口
*/
FlyBehavior flyBehavior;
public Duck(){}
/**
* 显示鸭子信息
*/
public abstract void display();
public void setFlyBehavior(FlyBehavior flyBehavior){
this.flyBehavior = flyBehavior;
}
public void quack() {
System.out.println("鸭字嘎嘎叫~");
}
public void swim(){
System.out.println("dack can swim");
}
public void fly(){
// 对fly进行改进
if (flyBehavior != null){
flyBehavior.fly();
}
}
}
// 不需要自己实现,只需要传入这个行为属性就行了
public class PekingDuck extends Duck{
@Override
public void display() {
System.out.println("Pecking Duck");
}
/**
* 假如北京鸭可以飞翔,但是飞翔技术一般
*/
public PekingDuck(){
flyBehavior = new BadFlyBehavior();
}
}
经过上面的改造,我们甚至可以动态的改变某个对象的行为。
public class Client {
public static void main(String[] args) {
PekingDuck pekingDuck = new PekingDuck();
pekingDuck.fly();
// 动态改变
pekingDuck.setFlyBehavior(new NoFlyBehavior());
pekingDuck.fly();
}
}