Java设计模式之策略模式Strategy
策略模式Strategy定义一系列算法,把它们封装起来,并且使它们可以相互替换。策略模式应用比较广泛,比如Java AWT的Layout manager,或者Gateway程序中的负载均衡策略等。总之,如果我们需要提供多种策略去实现某一种行为,可以使用策略模式。
策略模式实现起来比较简单,我们还是以负载均衡策略为例分析:
- IRule接口,里面只有一个方法,即选取下一个可用的item getNext(current)
- RandomRule,随机策略,从可选item中随机选取一个
- RoundRobinRule,轮询策略,顺序选取item中的下一个
- StrategyDemo,测试类
public interface IRule<T> {
T getNext(T currentItem);
}
public class RandomRule<T> implements IRule<T>{
private final List<T> items;
private final Random rand = new Random();
public RandomRule(List<T> rules){
this.items = rules;
}
@Override
public T getNext(T currentRule) {
int i = rand.nextInt(items.size());
return items.get(i);
}
}
public class RoundRobinRule<T> implements IRule<T>{
private final List<T> items;
public RoundRobinRule(List<T> rules){
this.items = rules;
}
@Override
public T getNext(T currentRule) {
int currentIndex = 0;
for (int i = 0; i < items.size(); i++) {
if (items.get(i).equals(currentRule)) {
currentIndex = i;
break;
}
}
int nextIndex = currentIndex == items.size() - 1 ? 0 : currentIndex + 1;
return items.get(nextIndex);
}
}
public class StrategyDemo {
public static void main(String[] args) {
List<String> items = new ArrayList<>();
for (int i = 0; i < 4; i++) {
items.add("Item " + i);
}
IRule<String> roundRobinRule = new RoundRobinRule<>(items);
test(roundRobinRule, items);
IRule<String> randomRule = new RandomRule<>(items);
test(randomRule, items);
}
private static void test(IRule<String> rule, List<String> items) {
System.out.println("Rule: " + rule.getClass().toString());
String current = items.get(0);
for (int i = 0; i < 10; i++) {
String item = rule.getNext(current);
System.out.println("Pick the item: " + item);
current = item;
}
}
}
程序最终输出如下,我们可以看到,对于轮询方式,item按1,2,3,0的顺序轮替出现,对于随机方式,item以一种随机方式出现。
Rule: class com.test.designpattern.strategy.RoundRobinRule
Pick the item: Item 1
Pick the item: Item 2
Pick the item: Item 3
Pick the item: Item 0
Pick the item: Item 1
Pick the item: Item 2
Pick the item: Item 3
Pick the item: Item 0
Pick the item: Item 1
Pick the item: Item 2
Rule: class com.test.designpattern.strategy.RandomRule
Pick the item: Item 2
Pick the item: Item 1
Pick the item: Item 2
Pick the item: Item 0
Pick the item: Item 0
Pick the item: Item 3
Pick the item: Item 1
Pick the item: Item 1
Pick the item: Item 0
Pick the item: Item 3