一、定义
策略模式,针对每一个不同的类型,调用具有共同接口的不同实现类,从而使得它们可以相互替换。
策略模式 ,针对实现同一接口的不同的类,采用不同的策略。比如,面对高级会员、初级会员会采用不同的折扣。
策略模式,可以避免大量的if和else。
二、角色
策略模式涉及到三个角色:
● 环境(Context)角色:调用策略
● 抽象策略(Strategy)角色:抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
● 具体策略(ConcreteStrategy)角色:实现抽象策略接口,包装了相关的算法或行为。
三、示例
- 策略模式接口 Strategy:
/**
* 策略模式接口
*
*/
public interface Strategy {
/**
* 做某事
* @param param
* @return
*/
String doSth(String param) ;
}
- 公共类:
/**
* 基础类,写不同策略的公共的代码,继承基础类,写公共逻辑,避免代码重复
*/
@Service
public class StrategyBaseService {
/**
* 公共代码,避免代码重复
*/
public void doCommon() {
System.out.println("do sth common.");
}
}
- 第一种策略 FirstStrategyServerImpl:
继承基础类,实现 Strategy接口。
@Component 注解的名称为 TypeNameConstant 常量,见后续代码。
/**
* 第一种策略
*/
@Component(TypeNameConstant.TYPE_FIRST)
public class FirstStrategyServerImpl extends StrategyBaseService implements Strategy {
/**
* 业务逻辑
*/
@Override
public String doSth(String param) {
doCommon();
return "FirstStrategy doSth " + param;
}
}
- 第二种策略 SecondStrategyServiceImpl:
/**
* 第二种策略
*/
@Component(TypeNameConstant.TYPE_SECOND)
public class SecondStrategyServiceImpl extends StrategyBaseService implements Strategy {
/**
* 业务逻辑
*/
@Override
public String doSth(String param) {
doCommon();
return "SecondStrategy doSth " + param;
}
}
- 不同策略的 @Component名称:
/**
* 不同策略的 @Component名称
*/
public class TypeNameConstant {
private TypeNameConstant() {}
/**
* 比如 FirstStrategy 的 @Component名称是 TypeConstant.TYPE_FIRST (这个常量对应字符串 first)
*/
public static final String TYPE_FIRST = "first";
public static final String TYPE_SECOND = "second";
public static final String TYPE_THIRD = "third";
}
- 类型枚举:
/**
* type枚举. @Getter 要是用不了,可以直接写 属性对应的 get()方法。
*/
@Getter
public enum TypeEnum {
/**
* 类型一
*/
FIRST_TYPE(1, TypeNameConstant.TYPE_FIRST),
/**
* 类型二
*/
SECOND_TYPE(2, TypeNameConstant.TYPE_SECOND),
/**
* 类型三
*/
THIRD_TYPE(3, TypeNameConstant.TYPE_THIRD),
;
/**
* 类型
*/
private final Integer type;
private final String typeName;
TypeEnum(Integer type, String text) {
this.type = type;
this.typeName = text;
}
/**
* 根据 type 获取枚举
* @param type
* @return
*/
public static TypeEnum getByType(Integer type) {
for (TypeEnum typeEnum : TypeEnum.values()) {
if (typeEnum.getType().equals(type)) {
return typeEnum;
}
}
return null;
}
public static TypeEnum getByName(String name) {
for (TypeEnum typeEnum : TypeEnum.values()) {
if (typeEnum.getTypeName().equals(name)) {
return typeEnum;
}
}
return null;
}
}
- StrategyContext 调用策略:
策略模式,会有一个 Context 类,调用策略。
/**
* 策略 Context,获取策略
*/
@Service
public class StrategyClientService {
@Resource
private StrategyContext strategyContext;
/**
* 根据 type 获取不同的策略,再执行业务逻辑。
*/
public String doSthByType(Integer type, String param) {
Strategy strategy = strategyContext.getStrategyByType(type);
return strategy.doSth(param);
}
}
- 根据类型,使用策略:
/**
* 调用类
*
*/
@Service
public class StrategyClientService {
@Resource
private StrategyContext strategyContext;
/**
* 根据 type 获取不同的策略,再执行业务逻辑。
*/
public String doSthByType(Integer type, String param) {
Strategy strategy = strategyContext.getStrategyByType(type);
return strategy.doSth(param);
}
}
测试代码
没有单元测试类,也可以直接写个 Controller 测试。
public void testDoSthByType() {
String result = strategyClientService.doSthByType(1, "12345");
System.out.println("==============> result: " + result);
}
输出结果:
type 为1时,结果为:
execute common method.
==============> result: FirstStrategy doSth 12345
type为2时,结果为:
execute common method.
==============> result: SecondStrategy doSth 12345
参考资料:
《java与模式》
标签:String,示例,TYPE,代码,实践,param,type,public,策略 From: https://www.cnblogs.com/expiator/p/18012557