策略模式

定义

定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。
行为型

适用场景

  • 系统由很多类,而他们的区别仅仅在于他们的行为不同;
  • 一个系统需要动态地在几种算法中选择一种。

优点和缺点

优点

  • 符合开闭原则
  • 避免使用多重条件转移语句
  • 提高算法的保密性和安全性

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 会产生很多策略类。

结构

  • 抽象策略类:定义了一个公共接口,各种不同的算法以不同的方法实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或者抽象类实现。
  • 环境策略类:实现了抽象策略定义的接口,提供具体的算法实现。
  • 环境类:持有一个策略类的引用,最终给客户端调用。

代码实现

假设有一个饭店,里面有许多中菜,都是由大厨来做的,根据不同的策略,大厨就可以做出来不同的菜
抽象策略类

1
2
3
public interface Strategy {
void friedDish();
}

菜肴1
具体策略类

1
2
3
4
5
6
public class Bouilli implements Strategy{
@Override
public void friedDish() {
System.out.println("红烧肉");
}
}

菜肴2
具体策略类

1
2
3
4
5
6
public class RoastDuck implements Strategy{
@Override
public void friedDish() {
System.out.println("烤鸭");
}
}

菜肴3
具体策略类

1
2
3
4
5
6
public class ShreddedPotatoes implements Strategy{
@Override
public void friedDish() {
System.out.println("土豆丝");
}
}

厨房
环境类:

1
2
3
4
5
6
7
8
9
10
11
12
public class Restaurant {

private Strategy strategy;

public Restaurant(Strategy strategy) {
this.strategy = strategy;
}

public void friedDish(){
strategy.friedDish();
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
public class Test {

public static void main(String[] args) {
Restaurant restaurant = new Restaurant(new Bouilli());
restaurant.friedDish();
System.out.println("-------------------");

Restaurant restaurant1 = new Restaurant(new ShreddedPotatoes());
restaurant1.friedDish();
}

}

结果:

1
2
3
红烧肉
-------------------
土豆丝

UML类图