涉及知识点:
枚举+枚举配置抽象类
函数式接口
设计模式
代码实例
- 策略模式,定义抽象接口,不同的实现类实现不同的策略
- 模板方法,定义一个模板方法,把公共流程写在模板方法中,然后不同的子类按需实现模板方法流程中的方法
- 单例和工厂是按需
1 2 3 4 5 6 7 8 9 10 11 12
| public interface AwardStrategy {
Map<String, Boolean> awardStrategy(String userId);
String getSource(); }
|
定义奖励发放模板流程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public abstract class BaseAwardTemplate { private static final Logger log = LoggerFactory.getLogger(BaseAwardTemplate.class);
public Boolean awardTemplate(String userId) { this.authentication(userId); this.risk(userId); return this.awardRecord(userId); }
protected void authentication(String userId) { log.info("{} 执行身份验证!", userId); }
protected void risk(String userId) { log.info("{} 执行风控校验!", userId); }
protected abstract Boolean awardRecord(String userId); }
|
实现不同渠道的奖励业务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| @Slf4j @Service public class ToutiaoAwardStrategyService extends BaseAwardTemplate implements AwardStrategy {
@Override public Boolean awardStrategy(String userId) { return super.awardTemplate(userId); }
@Override public String getSource() { return "toutiao"; }
@Override protected Boolean awardRecord(String userId) { log.info("头条渠道用户{}奖励50元红包!", userId); return Boolean.TRUE; } }
@Slf4j @Service public class WeChatAwardStrategyService extends BaseAwardTemplate implements AwardStrategy {
@Override public Boolean awardStrategy(String userId) { return super.awardTemplate(userId); }
@Override public String getSource() { return "wx"; }
@Override protected Boolean awardRecord(String userId) { log.info("微信渠道用户{}奖励100元红包!", userId); return Boolean.TRUE; } }
|
定义工厂方法,对外统一暴露业务调用入口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| @Component public class AwardStrategyFactory implements ApplicationContextAware { private final static Map<String, AwardStrategy> MAP = new HashMap<>();
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Map<String, AwardStrategy> beanTypeMap = applicationContext.getBeansOfType(AwardStrategy.class); beanTypeMap.values().forEach(strategyObj -> MAP.put(strategyObj.getSource(), strategyObj)); }
public Boolean getAwardResult(String userId, String source) { AwardStrategy strategy = MAP.get(source); if (Objects.isNull(strategy)) { throw new RuntimeException("渠道异常!"); } return strategy.awardStrategy(userId); }
private static class CreateFactorySingleton { private static AwardStrategyFactory factory = new AwardStrategyFactory(); }
public static AwardStrategyFactory getInstance() { return CreateFactorySingleton.factory; } }
|
业务入口方法:
1 2 3 4 5 6 7 8 9
| @RestController @RequestMapping("/activity") public class ActivityController {
@PostMapping("/reward3") public void reward3(String userId, String source) { AwardStrategyFactory.getInstance().getAwardResult(userId, source); } }
|
模板模式和策略模式的区别
策略模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| interface Strategy { public int doOperation(int num1, int num2); }
class OperationAdd implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 + num2; } }
class OperationSubtract implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 - num2; } }
class Context { private Strategy strategy;
public Context(Strategy strategy){ this.strategy = strategy; }
public int executeStrategy(int num1, int num2){ return strategy.doOperation(num1, num2); } }
|
模版模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| abstract class Game { abstract void initialize(); abstract void startPlay(); abstract void endPlay();
public final void play(){
initialize();
startPlay();
endPlay(); } }
class Cricket extends Game { void endPlay() { System.out.println("Cricket Game Finished!"); } void initialize() { System.out.println("Cricket Game Initialized! Start playing."); } void startPlay() { System.out.println("Cricket Game Started. Enjoy the game!"); } }
class Football extends Game { void endPlay() { System.out.println("Football Game Finished!"); } void initialize() { System.out.println("Football Game Initialized! Start playing."); } void startPlay() { System.out.println("Football Game Started. Enjoy the game!"); } }
|
从上面代码可以看出:
- 策略模式通过has-a的组合方式去实现,在代码运行的时候根据传入参数来动态的确定策略
- 模板模式通过is-a的继承方式去实现,每一个子类都代表一种不同的模板实现
所以策略和模板经常跟工厂一同出现:模板的抽象和子类决定实现流程,策略在运行的时候动态决定哪一个子目标,工厂用来生产
引自:https://mp.weixin.qq.com/s/qTmw1pHvzcMJPB6fbBHaZg