一.概念
策略模式 定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也称为政策模式(Policy)。(Definea family of algorithms,encapsulate each one, andmake them interchangeable. Strategy lets the algorithmvary independently from clients that use it.
)
策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。
二.设计原则
1.找出可能需要变化之处,把它们独立起来,不要和那些不需要变化的代码混在一起
2.针对接口编程,而不是针对实现编程
3.多用组合,少用继承
三.举例子
设计一只鸭子。没说是什么鸭子,所以包括各种各样的鸭子。想到的基本特性是鸭子会游泳,鸭子会呱呱叫,有的鸭子还会飞。。。。
</pre><pre name="code" class="java"><span style="white-space:pre"> </span>class Duck {
//想到了一个类的设计
public void swim() {
System.out.println("duck can swim");
}
public void quack() {
System.out.println("duck can quack,guaguagua..");
}
public void fly() {
System.out.println("duck maybe fly");
}
}
可不是所有的鸭子都会飞,都会走啊。。万一设计的是一直橡皮鸭子呢?他只会漂游,捏一下只会吱吱叫,可是不会飞。。。。
<span style="white-space:pre"> </span>class RubberDuck {//于是有想到了再创建一个类
public void swim() {
System.out.println("RubberDuck can swim");
}
public void quack() {
System.out.println("RubberDuck can quack, zhizhizhi...");
}
}
不料,现在出了一个火箭筒飞行器装备,可以装在橡皮鸭上,让橡皮鸭飞。。。总不好再去搞个装了飞行器的橡皮鸭类吧。
为了更好的设计,所以运用策略模式,把swim,walk,quack,fly单独封装成一个算法,抽象出一个行为的接口,把鸭子变为抽象父类。
/*
*策略模式 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
*/
public class Test {
abstract class Duck {
private FlyBehavior flyBehavior;
private QuackBehavior quackBehavior;
//保留不变的功能(当然为了更好的扩展,可以全部定义成单独的行为)
private void swim() {
System.out.println("duck can swim");
}
private void quack() {
this.quackBehavior.quack();
}
private void fly() {
this.flyBehavior.fly();
}
public void display() {
this.swim();
this.fly();
this.quack();
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
//定义会飞的策略接口
interface FlyBehavior {
public void fly();
}
//定义会叫的策略接口
interface QuackBehavior {
public void quack();
}
class FlyNoWay implements FlyBehavior {
public void fly() {
System.out.println("duck can't fly");
}
}
class FlyWithWing implements FlyBehavior {
public void fly() {
System.out.println("duck can fly with wing");
}
}
class FlyWithRocket implements FlyBehavior {
public void fly() {
System.out.println("duck can fly with rocket");
}
}
class GuaQuack implements QuackBehavior {
public void quack() {
System.out.println("duck can quack, guaguagua..");
}
}
class ZhiQuack implements QuackBehavior {
public void quack() {
System.out.println("duck can quack, zhizhizhi..");
}
}
class DonaldDuck extends Duck {
}
class RubberDuck extends Duck {
}
public static void main(String[] args) {
//定义一只唐老鸭
Duck donaldDuck = new Test().new DonaldDuck();
donaldDuck.setFlyBehavior(new Test().new FlyWithWing());
donaldDuck.setQuackBehavior(new Test().new GuaQuack());
donaldDuck.display();
System.out.println("=============================");
//定义一只橡皮鸭
Duck rubberDuck = new Test().new RubberDuck();
rubberDuck.setFlyBehavior(new Test().new FlyNoWay());
rubberDuck.setQuackBehavior(new Test().new ZhiQuack());
rubberDuck.display();
System.out.println("=============================");
//当橡皮鸭装备了火箭筒后
rubberDuck.setFlyBehavior(new Test().new FlyWithRocket());
rubberDuck.display();
}
}
运行结果:
四.理解
当出现更多装备的时候,也就是说有更多选择的策略的时候,策略模式是一种很好的选择。把不变的代码功能和经常要变的代码功能分开,便于更好的扩展,同时这样做让客户端有更好的选择。
总结:该对象的行为被封装进入一组类中,可以被轻易地扩充与改变。如果需要时,甚至在运行时也可以改变行为。