策略模式实现方式之Map<K,Function>
小概念
场景
- 我们有一个对象
- 对象有一个行为
- 该行为在不同场景中有不同的表现形式
策略模式
- 定义了一系列算法
- 封装了每个算法
- 这一系列的算法可互换代替
代码实现
定义一个对象行为表现形式枚举
//定义一个对象行为表现形式枚举
public enum AdApplyTypeEnum implements BaseEnum<Integer> {
/**
* 价值鉴定
*/
WORTH(1, "价值鉴定","JZJD",3);
Integer value;
/**
* 名称
*/
String name;
/**
* 申请单编号编码前缀
*/
String code;
/**
* 鉴定类型对应工作流模板类型
*/
Integer wfType;
AdApplyTypeEnum(Integer value, String name, String code,Integer wfType) {
this.value = value;
this.name = name;
this.code = code;
this.wfType = wfType;
}
/**
* 获取枚举值
*
* @return value
*/
@Override
public Integer getValue() {
return value;
}
/**
* 根据枚举值获取枚举类型
*
* @param value 枚举值
* @return FormStateEnum
*/
public static AdApplyTypeEnum valueOf(Integer value) {
for (AdApplyTypeEnum typeEnum : AdApplyTypeEnum.values()) {
if (typeEnum.getValue().equals(value)) {
return typeEnum;
}
}
return AdApplyTypeEnum.OTHER;
}
}
定义每种表现形式
/**
*价值
**/
private boolean updateWorth(AdApplyDataPO adApplyDataPO) {
}
/**
* 销毁
**/
private boolean updateDestroy(AdApplyDataPO adApplyDataPO) {
}
封装Map<K,Funtion> 和 初始化算法的对应的函数
/**
* 鉴定完成业务逻辑
*/
private final Map<AdApplyTypeEnum, Function<AdApplyDataPO, Boolean>> applyTypeBusinessLogicMap = new HashMap<>(16);
/**
* 初始化鉴定类型对应鉴定完成后业务逻辑
*/
@PostConstruct
private void initApplyTypeBusinessLogicMap() {
applyTypeBusinessLogicMap.put(AdApplyTypeEnum.WORTH, this::updateWorth);
applyTypeBusinessLogicMap.put(AdApplyTypeEnum.DESTROY, this::updateDestroy);
applyTypeBusinessLogicMap.put(AdApplyTypeEnum.DECRYPT, this::updateDecrypt);
applyTypeBusinessLogicMap.put(AdApplyTypeEnum.OPEN, this::updateOpen);
}
具体应用
//参数
AdApplyDataPO adApplyDataPO;
//K值
AdApplyTypeEnum adApplyType;
//调用
applyTypeBusinessLogicMap.get(adApplyType).apply(adApplyDataPO);
其他实现方式
利用java的多态特性
- 使用接口的多实现
- 子类继承父类重写父类的方法
代码实现
//StrategyExample test application
class StrategyExample {
public static void main(String[] args) {
Context context;
// Three contexts following different strategies
context = new Context(new FirstStrategy());
context.execute();
context = new Context(new SecondStrategy());
context.execute();
context = new Context(new ThirdStrategy());
context.execute();
}
}
// The classes that implement a concrete strategy should implement this
// The context class uses this to call the concrete strategy
interface Strategy {
void execute();
}
// Implements the algorithm using the strategy interface
class FirstStrategy implements Strategy {
public void execute() {
System.out.println("Called FirstStrategy.execute()");
}
}
class SecondStrategy implements Strategy {
public void execute() {
System.out.println("Called SecondStrategy.execute()");
}
}
class ThirdStrategy implements Strategy {
public void execute() {
System.out.println("Called ThirdStrategy.execute()");
}
}
// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {
Strategy strategy;
// Constructor
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void execute() {
this.strategy.execute();
}
}
还有一种在枚举中实现
但是这种我很少见到别人使用,不知道是不符合规范还是什么原因
不知道还有没有其他更好用的方式了
实现示例
enum PaymentStrategy {
CREDIT_CARD {
@Override
void pay(int amount) {
System.out.println("Paid " + amount + " dollars by credit card");
}
},
PAYPAL {
@Override
void pay(int amount) {
System.out.println("Paid " + amount + " dollars by PayPal");
}
};
abstract void pay(int amount);
}
public class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(PaymentStrategy.CREDIT_CARD);
cart.checkout(100);
cart.setPaymentStrategy(PaymentStrategy.PAYPAL);
cart.checkout(50);
}
}