遂宁网站建设公司,建设网站的标语,中国建设银行贵州省分行网站,国外网站如何搭建网页我们在开发时经常会遇到一堆的if else …, 或者switch, 比如我们常见的全局异常处理等, 像类似这种很多if else 或者多场景模式下, 策略模式是非常受欢迎的一种设计模式, 然而, 一个好的策略模式却不是那么容易写出来.
我在工作中也因为写烦了switch,if else 觉得很不优雅, 因…我们在开发时经常会遇到一堆的if else …, 或者switch, 比如我们常见的全局异常处理等, 像类似这种很多if else 或者多场景模式下, 策略模式是非常受欢迎的一种设计模式, 然而, 一个好的策略模式却不是那么容易写出来.
我在工作中也因为写烦了switch,if else 觉得很不优雅, 因此,我考虑是否有一套统一的解决方案呢?
思考我问题的初衷, 在什么策略下, 满足什么条件执行什么动作, 返回什么值, 这就是策略模式需要解决的核心问题, 大眼一看好似有点类似状态机? 然而它并不是状态机, 状态机是比较笨重, 而策略机应该是足够轻量的.
我们再来看核心问题,关于什么策略,满足什么条件执行什么动作,返回什么值, 是一个明显的dsl语法, 因此, 我的基本语法糖已确立: strategy.of().when().perform()或者strategy.of().perform(), 因为有时我们并不需要条件, 仅仅策略即可.
我们要实现上述语法糖, 就得设计一套规则, 使其可以满足dsl, 并且是合理的, 如此, 基本定义已确定, 如下:
/*** {link StrategyMachineBuilder}* param S strategy* param C context* param R result*/
public interface StrategyMachineBuilderS,C,R {OfS,C,R of(S s);StrategyMachineS,C,R build(String id);
}/*** {link Of}* param S strategy* param C context* param R result*/
public interface OfS,C,R {WhenS,C,R when(ConditionS,C,R condition);StrategyMachineBuilderS,C,R perform(ActionC,R action);
}/*** {link When}* param S strategy* param C context* param R result*/
public interface WhenS,C,R {StrategyMachineBuilderS,C,R perform(ActionC,R action);
}/*** {link Condition}* param S strategy* param C context* param R result*/
public interface ConditionS,C,R {boolean isSatisfied(S s,C c);
}
/*** {link Action}* param C context* param R result*/
public interface ActionC,R {R apply(C c);
}/*** {link Strategy}* param S strategy* param C context* param R result*/
public interface StrategyS, C, R {S strategy();ConditionS,C,R condition();ActionC, R action();StrategyS,C,R strategy(S s);StrategyS,C,R condition(ConditionS,C,R condition);StrategyS,C,R action(ActionC,R action);
}
/*** {link StrategyMachine}* param S strategy* param C context* param R result*/
public interface StrategyMachineS,C,R {R apply(S s, C c);
}如此: 架构已经构建完毕, 剩下的工作就很简单了, 实现此架构即可.
/*** {link StrategyMachineBuilderImpl}* param S strategy* param C context* param R result*/
class StrategyMachineBuilderImplS,C,R implements StrategyMachineBuilderS,C,R{private final MapS, ListStrategyS,C,R map new ConcurrentHashMap();Overridepublic OfS, C, R of(S s) {map.computeIfAbsent(s, k - new ArrayList());StrategyS,C,R strategy new StrategyImpl();map.get(s).add(strategy);return new OfImpl(strategy);}Overridepublic StrategyMachineS, C, R build(String id) {StrategyMachineImplS, C, R machine new StrategyMachineImpl(map);StrategyCache.put(id, machine);return machine;}public class OfImpl implements OfS,C,R{private final StrategyS,C,R strategy;OfImpl(StrategyS,C,R strategy){this.strategy strategy;}Overridepublic WhenS, C, R when(ConditionS,C,R condition) {this.strategy.condition(condition);return new WhenImpl(strategy);}Overridepublic StrategyMachineBuilderS, C, R perform(ActionC, R action) {this.strategy.action(action);return StrategyMachineBuilderImpl.this;}}public class WhenImpl implements WhenS,C,R {private final StrategyS,C,R strategy;WhenImpl(StrategyS,C,R strategy){this.strategy strategy;}Overridepublic StrategyMachineBuilderS, C, R perform(ActionC, R action) {this.strategy.action(action);return StrategyMachineBuilderImpl.this;}}public class StrategyImpl implements StrategyS, C, R {private S strategy;private ConditionS,C,R condition;private ActionC, R action;Overridepublic S strategy() {return this.strategy;}Overridepublic ConditionS,C,R condition() {return this.condition;}Overridepublic ActionC, R action() {return this.action;}Overridepublic StrategyS, C, R strategy(S s) {this.strategy s;return this;}Overridepublic StrategyS, C, R condition(ConditionS,C,R condition) {this.condition condition;return this;}Overridepublic StrategyS, C, R action(ActionC, R action) {this.action action;return this;}}
}/*** Strategy Machine Impl* param S strategy* param C context* param R result*/
class StrategyMachineImplS,C,R implements StrategyMachineS,C,R {private final MapS, ListStrategyS,C,R map;public StrategyMachineImpl(MapS, ListStrategyS,C,R map){this.map map;}Overridepublic R apply(S s, C c) {ListStrategyS, C, R strategies map.get(s);if (strategiesnull||strategies.isEmpty()){throw new RuntimeException(no strategy found for s);}for (StrategyS, C, R strategy : strategies) {// 如果没有condition直接执行actionif (strategy.condition()null) {return strategy.action().apply(c);}// 如果有condition先判断是否满足condition满足则执行actionif (strategy.condition().isSatisfied(s,c)){return strategy.action().apply(c);}}// 未发现策略关于s的conditionthrow new RuntimeException(no strategy found of met condition for s);}
}/*** Strategy Machine Factory*/
public class StrategyMachineFactory {public static S,C,R StrategyMachineBuilderS,C,R create() {return new StrategyMachineBuilderImpl();}public static S,C,R StrategyMachineS,C,R get(String id) {return (StrategyMachineS, C, R) StrategyCache.get(id);}
}/*** {link StrategyCache}*/
class StrategyCache {private static final MapString,StrategyMachine?,?,? CACHE new java.util.concurrent.ConcurrentHashMap();public static void put(String id, StrategyMachine?,?,? machine) {CACHE.put(id, machine);}public static StrategyMachine?,?,? get(String id) {return CACHE.get(id);}
}如此, 策略机已实现完毕. 下面给出两种场景例子 一. 不同年龄吃不同分量的药 Example: Under the age of 12, take 20 milligrams of medication per day; 12-18 years old, taking 30 milligrams a day 18-30 years old, taking 40 milligrams a day 30-50 years old, taking 45 milligrams a day Eating 42 milligrams for those over 50 years old
class MedicineStrategy {private static StrategyMachineString, MedicineContext, Void strategy;static {StrategyMachineBuilderString, MedicineContext, Void machineBuilder StrategyMachineFactory.create();strategy machineBuilder.of().when((s, c) - c.age 12).perform((c) - {System.out.println(Under the age of 12, take 20 milligrams of medication per day;);return Void.TYPE.cast(null);}).of().when((s, c) - c.age 12 c.age 18).perform((c) - {System.out.println(12-18 years old, taking 30 milligrams a day);return Void.TYPE.cast(null);}).of().when((s, c) - c.age 18 c.age 30).perform((c) - {System.out.println(18-30 years old, taking 40 milligrams a day);return Void.TYPE.cast(null);}).of().when((s, c) - c.age 30 c.age 50).perform((c) - {System.out.println(30-50 years old, taking 45 milligrams a day);return Void.TYPE.cast(null);}).of().when((s, c) - c.age 50).perform((c) - {System.out.println(Eating 42 milligrams for those over 50 years old);return Void.TYPE.cast(null);}).build(medicine);}public static StrategyMachineString, MedicineContext, Void get() {// StrategyMachineString, MedicineContext, Void strategy StrategyMachineFactory.get(medicine);return strategy;}DataAllArgsConstructorNoArgsConstructorpublic static class MedicineContext {private int age;}public static void main(String[] args) {get().apply(, new MedicineContext(10));}}二. 计算机 StrategyMachineBuilderString, StrategyContext, Number machineBuilder StrategyMachineFactory.create();machineBuilder.of(加法).perform(strategyContext - strategyContext.a strategyContext.b);machineBuilder.of(减法).perform(strategyContext - strategyContext.a - strategyContext.b);machineBuilder.of(乘法).perform(strategyContext - strategyContext.a * strategyContext.b);// 除法,当c1时,忽略小数位, 当c2时不忽略machineBuilder.of(除法).when((s, strategyContext) - strategyContext.c 1).perform(strategyContext - strategyContext.a / strategyContext.b);machineBuilder.of(除法).when((s, strategyContext) - strategyContext.c 2).perform(strategyContext - (strategyContext.a * 1.0d) / (strategyContext.b * 1.0d));StrategyMachineString, StrategyContext, Number strategyMachine machineBuilder.build(test);// StrategyMachineString, StrategyContext, Number strategyMachine StrategyMachineFactory.get(test);System.out.println(strategyMachine.apply(加法, new StrategyContext(1, 2, 1)));System.out.println(strategyMachine.apply(减法, new StrategyContext(1, 2, 1)));System.out.println(strategyMachine.apply(乘法, new StrategyContext(1, 2, 1)));System.out.println(strategyMachine.apply(除法, new StrategyContext(1, 2, 1)));System.out.println(strategyMachine.apply(除法, new StrategyContext(1, 2, 2)));源码地址: https://github.com/zhangpan-soft/dv-commons