一、策略模式概念
策略模式定义了不同的算法,然后将它们分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
就好比,在足球场上11个运动员的行为就可以看作算法,他们是分别独立的,场上11个队员也可以相互替换(当然正式比赛中不会发生这样的事)。教练员可以看作是客户,他可以在场边指挥11个人中的某一个人的行为发生变化而不影响其他人的行为。
二、使用场景
场景1: 众多类之间仅仅是行为上有差异,而客户需要动态的在这些类中选择一个,这时候就可以使用策略模式。比如,足球场上运动员们都是在踢足球,它们的差异仅仅是有的人需要防守,有的人需要进攻,而教练员需要做的就是在场边动态的指挥谁来防守,谁去进攻。
场景2: 使用者不需要知道具体怎么实现的情况。比如,场边的教练不需要知道进攻队员是加速过人还是花式动作过人,他只需要指挥队员过人就OK了。
场景3: 在一个类里有多种行为,而这些行为在这个类中以多个条件语句的形式操作的。比如,队员A,if(进攻){进攻}else if(防守){防守},这时候就可以采用策略模式来代替条件语句。
三、结构
从上面的UML图中我们可以看出策略模式由三个部分组成:
1. 环境类(Player):它维护一个Strategy引用,通过环境类来调用具体策略。
2. 策略接口(Strategy):它定义了所有具体策略需要实现的方法。
3. 具体策略实现类:实现具体的算法
四、实现
为了便于查看,所以将所有的代码放在同一个类中。
/**
* Description: 策略模式
* Designer: jack
* Date: 2017/8/4
* Version: 1.0.0
*/
public class Manager {
public static void main(String[] args) {
Player playerA = new Player(new AttackStarategy());
playerA.execute();
playerA = new Player(new OverSideStrategy());
playerA.execute();
}
}
/**
* 环境类(球员)
*/
class Player {
private Strategy strategy;
public Player(Strategy strategy) {
this.strategy = strategy;
}
//执行具体都战术
public void execute(){
strategy.executeStrategy();
}
}
/**
* 策略接口(战术)
*/
interface Strategy {
void executeStrategy();
}
/**
* 具体策略实现类(越位战术)
*/
class OverSideStrategy implements Strategy {
@Override
public void executeStrategy() {
System.out.println("采用越位战术!");
}
}
/**
* 具体策略实现类(进攻战术)
*/
class AttackStarategy implements Strategy {
@Override
public void executeStrategy() {
System.out.println("采用进攻战术!");
}
}
五、优点
在说优点之前,我们先来看看如果不使用设计模式的话上面的例子该如何实现。
public class Manager {
public static void main(String[] args) {
Player playerA = new Player();
playerA.execute(1);
playerA.execute(2);
}
}
class Player{
public void execute(int strategy){
if (strategy == 1) {
System.out.println("采用进攻战术!");
} else if (strategy == 2) {
System.out.println("采用越位战术!");
}
}
}
朋友们咋一看会不会感觉不使用设计模式比使用设计模式的代码看上去要少好多。但是我这里只列出了两种战术,如果有几十种战术,不使用设计模式的话我们还需要在Player的execute中添加几十个if-else,这样的代码维护起来成本可想而知。
六、局限性
当然,设计模式也有它自己的局限性:
1. 使用者必须具体的指导具体策略的实现之间的差别才能准确的使用对应的策略,这就导致策略实现不得不向客户暴露;
2. 如果策略多对会导致策略类相当庞大。
不过世界上没有十全十美的模式,每个设计模式都有它适用的地方,只要我们的使用方式得当,那么策略模式可以帮助我们写出漂亮优雅的代码。
------------------------------------------------------------------------------
欢迎关注我的个人公众号,推送最新文章