策略模式(Strategy),定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。策略模式主要解决在有多种相似算法的情景下,使用if...else所带来的复杂和难以维护。
小孩喜欢花花绿绿各种不同的色彩,以小孩穿不同颜色的衣服为例。有一个抽象的衣服选择器接口,派生出红色衣服选择器、白色衣服选择器、蓝色衣服选择器,衣服类持有衣服选择器的引用。
这里涉及到3个角色:
- 环境角色:持有抽象策略的引用。
- 抽象策略角色:通常是一个接口或抽象类,在这里就是衣服选择器。
- 具体策略角色:封装了相关算法,这里指的是不同颜色的衣服选择器。
- 衣服选择器
public interface ClothesChooser {
void dress();
}
- 红色衣服选择器
public class RedClothesChooser implements ClothesChooser {
@Override
public void dress() {
System.out.print("dress red clothes");
}
}
- 白色衣服选择器
public class WhiteClothesChooser implements ClothesChooser {
@Override
public void dress() {
System.out.print("dress white clothes");
}
}
- 蓝色衣服选择器
public class BlueClothesChooser implements ClothesChooser {
@Override
public void dress() {
System.out.print("dress blue clothes");
}
}
- 衣服
public class Clothes {
public ClothesChooser clothesChooser;
public Clothes(ClothesChooser clothesChooser) {
this.clothesChooser = clothesChooser;
}
public void dress() {
clothesChooser.dress();
}
}
- 客户端测试类
public class Client {
public static void main(String[] args) {
ClothesChooser clothesChooser = new RedClothesChooser();
Clothes clothes = new Clothes(clothesChooser);
clothes.dress();
}
}
运行结果:
dress red clothes
在这里,具体策略即红色、白色、蓝色的衣服选择器,有一个特点,就是它们之间是平等的,并且它们做的是同一件事情,都是选择一件衣服来穿,不同之处在于所选择衣服的颜色不同。
策略模式的优点在于算法可以自由切换,并且避免了多重条件判断。
但是策略模式的缺点也很明显,策略类会增多,并且所有的策略类都需要对外暴露,这就意味着客户端必须知道各种算法的区别。