
策略模式定义了一系列算法(算法族),各可以相互替换,客户端可根据实际情况选择使用哪一种算法,算法的变化不会影响使用算法的客户。
策略模式核心结构:
1.抽象策略接口或抽象类 Strategy:具体的策略的规范。
2.具体策略类 Concrete Strategy :抽象策略的实现类。
3. 上下文策略类 Context:持有一个策略类的引用,最终给客户端调用。
UML类图如下:

下面我们以实例来理解策略模式的运用:
中国移动对不同客户群有不同的流量套餐,同样是50元套餐,普通用户可获得流量50G,全球通用户可获得100G,企业用户可获得200G,对,中国移动就是这么黑。营业厅办理业务时,根据用户不同类型,提供不同的流量策略。

package net.mosang.strategy;
public interface Strategy {
public int getStrategy(int standardDataFlow); //标准手机流量
package net.mosang.strategy;
/**
* 抽象策略类
* @author Heiry
*
*/
public interface Strategy {
public int getStrategy(int standardDataFlow); //标准手机流量
}
package net.mosang.strategy;
/**
* 抽象策略类
* @author Heiry
*
*/
public interface Strategy {
public int getStrategy(int standardDataFlow); //标准手机流量
}
package net.mosang.strategy;
public class standard implements Strategy {
public int getStrategy(int standardDataFlow) {
System.out.println("普通用户,每月"+standardDataFlow+"流量。");
package net.mosang.strategy;
/**
* 普通用户策略:50G/月
* @author Heiry
*
*/
public class standard implements Strategy {
@Override
public int getStrategy(int standardDataFlow) {
System.out.println("普通用户,每月"+standardDataFlow+"流量。");
return standardDataFlow;
}
}
package net.mosang.strategy;
/**
* 普通用户策略:50G/月
* @author Heiry
*
*/
public class standard implements Strategy {
@Override
public int getStrategy(int standardDataFlow) {
System.out.println("普通用户,每月"+standardDataFlow+"流量。");
return standardDataFlow;
}
}
package net.mosang.strategy;
public class GSM implements Strategy {
public int getStrategy(int standardDataFlow) {
System.out.println("全球通用户,每月"+standardDataFlow*2+"G流量。");
return standardDataFlow*2;
package net.mosang.strategy;
/**
* 全球通用户策略:100G/月
* @author Heiry
*
*/
public class GSM implements Strategy {
@Override
public int getStrategy(int standardDataFlow) {
System.out.println("全球通用户,每月"+standardDataFlow*2+"G流量。");
return standardDataFlow*2;
}
}
package net.mosang.strategy;
/**
* 全球通用户策略:100G/月
* @author Heiry
*
*/
public class GSM implements Strategy {
@Override
public int getStrategy(int standardDataFlow) {
System.out.println("全球通用户,每月"+standardDataFlow*2+"G流量。");
return standardDataFlow*2;
}
}
package net.mosang.strategy;
public class Enterprise implements Strategy {
public int getStrategy(int standardDataFlow) {
System.out.println("企业用户,每月"+standardDataFlow*4+"G流量。");
return standardDataFlow*4;
package net.mosang.strategy;
/**
* 企业用户策略:200G/月
* @author Heiry
*
*/
public class Enterprise implements Strategy {
@Override
public int getStrategy(int standardDataFlow) {
System.out.println("企业用户,每月"+standardDataFlow*4+"G流量。");
return standardDataFlow*4;
}
}
package net.mosang.strategy;
/**
* 企业用户策略:200G/月
* @author Heiry
*
*/
public class Enterprise implements Strategy {
@Override
public int getStrategy(int standardDataFlow) {
System.out.println("企业用户,每月"+standardDataFlow*4+"G流量。");
return standardDataFlow*4;
}
}
package net.mosang.strategy;
private Strategy strategy ; //持有对具体策略的引用
public void getStrategy(int i) {
strategy.getStrategy(i); //调用具体策略
public Context(Strategy strategy) {
this.strategy = strategy;
public Strategy getStrategy() {
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
package net.mosang.strategy;
/**
* 上下文类,用于策略切换和客户端调用;
* 通过上下文类,算法与客户端类分离
* @author Heiry
*
*/
public class Context {
private Strategy strategy ; //持有对具体策略的引用
public void getStrategy(int i) {
strategy.getStrategy(i); //调用具体策略
}
public Context(Strategy strategy) {
this.strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
}
package net.mosang.strategy;
/**
* 上下文类,用于策略切换和客户端调用;
* 通过上下文类,算法与客户端类分离
* @author Heiry
*
*/
public class Context {
private Strategy strategy ; //持有对具体策略的引用
public void getStrategy(int i) {
strategy.getStrategy(i); //调用具体策略
}
public Context(Strategy strategy) {
this.strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
}
package net.mosang.strategy;
public static void main(String[] args) {
int standardFlow = 50 ; //普通基础流量50G
Strategy s2 = new Enterprise();
Strategy s3 = new standard();
Context c1 = new Context(s1);
c1.getStrategy(standardFlow);
System.out.println("#####################################");
Context c2 = new Context(s2);
c2.getStrategy(standardFlow);
System.out.println("#####################################");
Context c3 = new Context(s3);
c3.getStrategy(standardFlow);
package net.mosang.strategy;
/**
* 客户端类
* @author Heiry
*
*/
public class Client {
public static void main(String[] args) {
int standardFlow = 50 ; //普通基础流量50G
Strategy s1 = new GSM();
Strategy s2 = new Enterprise();
Strategy s3 = new standard();
Context c1 = new Context(s1);
c1.getStrategy(standardFlow);
System.out.println("#####################################");
Context c2 = new Context(s2);
c2.getStrategy(standardFlow);
System.out.println("#####################################");
Context c3 = new Context(s3);
c3.getStrategy(standardFlow);
}
}
package net.mosang.strategy;
/**
* 客户端类
* @author Heiry
*
*/
public class Client {
public static void main(String[] args) {
int standardFlow = 50 ; //普通基础流量50G
Strategy s1 = new GSM();
Strategy s2 = new Enterprise();
Strategy s3 = new standard();
Context c1 = new Context(s1);
c1.getStrategy(standardFlow);
System.out.println("#####################################");
Context c2 = new Context(s2);
c2.getStrategy(standardFlow);
System.out.println("#####################################");
Context c3 = new Context(s3);
c3.getStrategy(standardFlow);
}
}
输出结果:
#####################################
#####################################
全球通用户,每月100G流量。
#####################################
企业用户,每月200G流量。
#####################################
普通用户,每月50流量。
全球通用户,每月100G流量。
#####################################
企业用户,每月200G流量。
#####################################
普通用户,每月50流量。
通过以上实例,我们看到,策略模式避免了复杂策略而不可避免的庞大而难以维护的if…else判断,可以在不修改原代码的情况下,灵活增加新算法,符合开闭原则。