定义一系列算法,将每个算法都封装起来,并且它们可以互换。策略模式是一种对象行为模式。
一个行为触发业务逻辑计算,行为可能根据其属性使用不同的策略进行执行
比如订单事件进来之后进行活动的计算,新用户执行策略NewUserRewardStrategyA,老用户执行策略OldUserRewardStrategyA,可通过扩充RewardStrategy的子类来扩充不同属性用户的奖励计算策略
/**
* 抽象一个策略
* @author: nanxi
* @date: 2021/7/28
* @time: 2:51 下午
*/
public abstract class RewardStrategy {
public abstract long reward(long userId);
public void rewardAndSettlement(long userId, long rewardMoney) {
// todo 实现
System.out.println("userId: " + userId + " rewardMoney: " + rewardMoney);
}
}
// 老用户的奖励策略
public class OldUserRewardStrategyA extends RewardStrategy {
@Override
public long reward(long userId) {
return 200;
}
}
// 新用户的奖励策略
public class NewUserRewardStrategyA extends RewardStrategy {
@Override
public long reward(long userId) {
return 500;
}
}
// 使用策略模式执行策略
public class RewardContext {
// 奖励策略
private RewardStrategy rewardStrategy;
public RewardContext(RewardStrategy rewardStrategy) {
this.rewardStrategy = rewardStrategy;
}
public void doStrategy(long userId) {
long rewardMoney = rewardStrategy.reward(userId);
rewardStrategy.rewardAndSettlement(userId, rewardMoney);
}
}
----------------------------------------------------------------------------------------------------------------
// 工厂类抽象类:用来生产奖励策略
public abstract class StrategyFactory<T> {
abstract RewardStrategy createRewardStrategy(Class<T> c);
}
// 工厂生产类
public class RewardStrategyFactory extends StrategyFactory {
// 根据传入的不同策略的class生成对应的实例
@Override
RewardStrategy createRewardStrategy(Class c) {
RewardStrategy product = null;
try {
product = (RewardStrategy) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return product;
}
}
public class TestMain {
/**
* 主流程:创建工厂 -> 使用工厂创建具体的奖励策略 -> 使用封装的策略,实现对策略的访问和执行
* @param args
*/
public static void main(String[] args) {
// 创建工厂
RewardStrategyFactory factory = new RewardStrategyFactory();
// todo 根据场景确定一个具体的策略实现类:NewUserRewardStrategyA
// 使用工厂创建一个具体的奖励策略
RewardStrategy newUserReward = factory.createRewardStrategy(NewUserRewardStrategyA.class);
// 执行封装的策略,实现对策略的访问和执行
RewardContext rewardContext = new RewardContext(newUserReward);
rewardContext.doStrategy(1);
}
}