一、什么是策略模式
策略这个词应该怎么理解,打个比方说,我们出门的时候会选择不同的出行方式,比如骑自行车、坐公交、坐火车、坐飞机、坐火箭等等,这些出行方式,每一种都是一个策略。
再比如我们去逛商场,商场现在正在搞活动,有打折的、有满减的、有返利的等等,其实不管商场如何进行促销,说到底都是一些算法,这些算法本身只是一种策略,并且这些算法是随时都可能互相替换的,比如针对同一件商品,今天打八折、明天满100减30,这些策略间是可以互换的。
策略模式(Strategy),定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。UML结构图如下:
其中,Context是上下文,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用;Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。
二.设计原则:
设计原则有很多,这里直接说策略模式中使用到的,参看实例思考哪些地方用到下面的设计模式:
1.封装变化(找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混合在一起。)
2.针对接口,超类编程,而不是针对实现编程。(案例中可以用IspeedBechavior借口代替速度行为,每种具体的行为实现其中一个接口)
3.多用组合,少用继承。(由于接口的特性可以任意组合,而继承每个类只能继承一个,会导致方法重写代码量增大)
三。策略模式的实现及实例:
假设我们开发一个植物大战僵尸游戏,要求是所有僵尸的必要条件是可以动的,可以攻击,外观上区分就可以了。
写一个抽象类Character,然后让所有角色继承这个类就可以了。
抽象类:
public abstract class Character {
//移动
void move() {
System.out.println("move");
}
//攻击
void attack() {
System.out.println("attack");
}
abstract void display();
}
红头僵尸:
public class RedHeadZombie extends Character{
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("My head is Red");
}
}
绿头僵尸:
public class GreenHeadZombie extends Character {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("My head is Green");
}
}
写完了,问题解决,然而又有新需求了,要求速度要有区别,那就在抽象类中添加
abstract void speed();抽象方法,让红头和绿头分别实现。
然而又有要求了,需要不同的攻击方式,那就重写attack()方法就行了
子类中实现 void attack(){}
最终修改完成,速度和颜色和攻击方式都不一样了,但是都是僵尸。以上就是用的策略模式。
所以策略模式就是,分别将程序中变化的部分封装起来,让他们之间可以相互替换。策略模式可以让算法的变化独立于使用算法的客户。
4.策略模式的优缺点:
优点:
1)算法可以自由切换。
2)避免使用多重条件判断。
3)扩展性良好。
缺点:
1)策略类会增多。
2)所有策略类都需要对外暴露。