demo
/**
- 抽象策略角色
- 定义具体策略类需要实现的方法
/
public interface PayStrategy {
/*
- 假设会返回一个支付页面 *
- @return {@link String } 支付页面 */ public String toPayHtml(); } ```
具体策略角色
支付宝支付策略类
/*** 具体策略角色* alipay*/public enum AlipayStrategyImpl implements PayStrategy {SINGLETON;@Overridepublic String toPayHtml() {return "假设是支付宝页面";}public static PayStrategy getSingleton() {System.out.println("获取单例");return SINGLETON;}}
微信支付策略类 ```java /**
- 具体策略角色
weixin pay */ public enum WexinPayStrategyImpl implements PayStrategy { SINGLETON ; @Override public String toPayHtml() { return “假设是微信支付页面”; }
public static PayStrategy getSingleton() { System.out.println(“获取单例”); return SINGLETON; } }
<a name="xCNFS"></a>#### 一个常量- 定义支付渠道 id 和具体实现策略类 class 的映射- 也可以改为 支付渠道 id 和具体实现策略类类名的映射- 也可以将类名存储在 db 中```java/*** 支付策略枚举* 对应 支付渠道id-具体的支付实现策略类 class*/public enum PayStrategyClassName {ALIPAY_STRATEGY(1, AlipayStrategyImpl.class),WEXINIPAY_STRATEGY(2, WexinPayStrategyImpl.class),;/*** 渠道 id*/private int channelId;/*** 具体的支付实现策略类的 class*/private Class<? extends PayStrategy> className;/*** 根据 channelId 获取对应的策略实现类名** @param channelId 支付渠道 id* @return*/public static Class<? extends PayStrategy> getPayStrategy(int channelId) {for (PayStrategyClassName payStrategyClassName: values()) {if (payStrategyClassName.channelId == channelId) {return payStrategyClassName.className;}}return null;}PayStrategyClassName(int channelId, Class<? extends PayStrategy> className) {this.channelId = channelId;this.className = className;}public int getChannelId() {return channelId;}public Class<? extends PayStrategy> getClassName() {return className;}}
环境角色
会对获得的具体策略实现类对象进行缓存
- 减少并发问题,此处缓存了具体策略实现的单例对象
也可以在 map 的 get and set 进行锁
/*** 1. 环境角色*/public final class PayStrategyFactory {private PayStrategyFactory() {}/*** 获取单例的方法名*/private static String targetMethodName = "getSingleton";/*** 缓存*/private static Map<String, PayStrategy> payStrategyMap = new ConcurrentHashMap<>(2);/*** 根据类名 获得 具体策略实现类** @param className 具体策略实现类的类名* @return {@link PayStrategy}*/public static PayStrategy getPayStrategy(String className) {if (Objects.isNull(className) || "".equals(className)) {return null;}if (Objects.isNull(payStrategyMap.get(className))) {try {// 反射获得具体策略实现类 classClass<?> clz = Class.forName(className);Method method = clz.getDeclaredMethod(targetMethodName);// 调用获取单例的静态方法PayStrategy payStrategySingletonInstance = (PayStrategy) method.invoke(null);// 进行缓存payStrategyMap.put(className, payStrategySingletonInstance);System.out.println("缓存支付策略单例ing");return payStrategySingletonInstance;} catch (Exception e) {// TODO start loggere.printStackTrace();return null;}} else {System.out.println("从缓存中获取了支付策略单例");return payStrategyMap.get(className);}}}
调用和输出
调用 ```java public class PayService { public static void startPay(int channelId) {
// 1. 通过渠道 id 获得 类名称Class<?> cLassName = PayStrategyClassName.getPayStrategy(channelId);if (Objects.isNull(cLassName)) {System.out.println("没有对应的支付渠道");return;}// 策略 + 单例 获得具体策略实现类PayStrategy payStrategy = PayStrategyFactory.getPayStrategy(cLassName.getName());if (Objects.nonNull(payStrategy)){System.out.println(payStrategy.toPayHtml());} else {System.out.println("没有对应的支付策略");}
} }
class Main { public static void main(String[] args) { PayService.startPay(0); System.out.println(“==============”); PayService.startPay(1); System.out.println(“==============”); PayService.startPay(1); System.out.println(“==============”); PayService.startPay(1); System.out.println(“——————-“); PayService.startPay(2); System.out.println(“——————-“); PayService.startPay(2); } }
- 输出```shell没有对应的支付渠道==============获取单例缓存支付策略单例ing假设是支付宝页面==============从缓存中获取了支付策略单例假设是支付宝页面==============从缓存中获取了支付策略单例假设是支付宝页面-------------获取单例缓存支付策略单例ing假设是微信支付页面-------------从缓存中获取了支付策略单例假设是微信支付页面Process finished with exit code 0
