一、概念
官方理解:策略模式是针对数据对象的行为模式,用意是针对一组策略,将每一个策略封装到具有共同接口的独立的类中,从而使得他们可以相互替换。
通俗的讲:我封装了很多相同level的策略,通过java的多态机制,使他们可以等价的替换。换句话说,就是相同的行为,不同的实现。
二、举一个实践例子
需求:描述狗狗。狗狗都会叫,都会奔跑,但是狗狗有不同的颜色,狗狗有不同的特殊功能(比如:导盲,寻找物品等)
需求分析:根据java的特性,想要全面,精简的描述狗狗的特征,需要把相同的和变化的特征都抽象出来,分别处理:
1.相同的特征可以抽象在父类中,比如 狗叫,奔跑,不同颜色(只是颜色不同,方式相同也可以抽象出来)
2.变化的特征,比如导盲,寻找物品等,这些特征的动作/反馈都不一样,但是又是同等重要,都属于狗狗的特殊能力,所以可以封装为不同的特殊能力,赋给有这个能力的狗狗。
设计模式剖析:变化的特征的抽取和封装,就用到策略模式。将狗狗的特殊能力封装成同level的策略,可以相互替换。
三、代码实践
dog类:
public class Dog {
//各种行为策略的公共接口 即狗狗的不同的特殊功能
private BehaviorStrategy behaviorStrategy;
public Dog(BehaviorStrategy behaviorStrategy) {
this.behaviorStrategy = behaviorStrategy;
}
//狗狗的不同特殊功能
public void specialBeavior() {
behaviorStrategy.behavior();
}
//狗狗都会叫
public void bark() {
System.out.println("wang wang wang");
}
//狗狗都会奔跑
public void run() {
System.out.println("run");
}
//狗狗有不同的颜色
public void display() {
System.out.println("no color");
}
}
绿色狗狗类:
public class GreenDog extends Dog {
public GreenDog(BehaviorStrategy behaviorStrategy) {
super(behaviorStrategy);
}
@Override
public void display() {
System.out.println("i am green");
}
}
红色狗狗类:
public class RedDog extends Dog {
public RedDog(BehaviorStrategy behaviorStrategy) {
super(behaviorStrategy);
}
@Override
public void display() {
System.out.println("i am red");
}
}
黄色狗狗类:
public class YellowDog extends Dog {
public YellowDog(BehaviorStrategy behaviorStrategy) {
super(behaviorStrategy);
}
@Override
public void display() {
System.out.println("i am yellow");
}
}
特殊能力接口:
public interface BehaviorStrategy {
public void behavior();
}
导盲能力类:
public class GuideWay implements BehaviorStrategy {
@Override
public void behavior() {
System.out.println("i can guide way");
}
}
寻物能力类:
public class SearchItems implements BehaviorStrategy {
@Override
public void behavior() {
System.out.println("i can search items");
}
}
测试类:
public class DogTest {
public static void main(String[] args) {
GuideWay guideWay = new GuideWay();
SearchItems searchItems = new SearchItems();
//绿色狗狗会导盲
GreenDog greenDog = new GreenDog(guideWay);
//黄色狗狗会寻物
YellowDog yellowDuck = new YellowDog(searchItems);
greenDog.specialBeavior();
yellowDuck.specialBeavior();
}
}
输出结果:
i can guide way
i can search items
Process finished with exit code 0
四、总结
策略模式的优点:
1.策略模式提供了管理同level策略的办法,策略类的等级结构定义了一个策略,恰当使用继承可以把公共的的代码移动到父类里面,从而避免代码重复。比如,把狗狗都会的叫和奔跑等方法抽象到父类dog中,在父类dog中用接口类型的成员变量BehaviorStrategy,管理不同的特殊能力的实现类。
2.使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护。
策略模式的缺点:
1.调用者必须知道所有的策略类,才能决定使用哪一个策略类。比如,必须知道什么颜色的狗狗有什么特殊能力,才能精确描述。
2.由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数量就会很多。比如,如果狗狗的特殊能力很多,就会封装很多的类,使程序复杂化。