首先来看一个demo!!
publicinterface IPay {
void pay();
}
@Service
publicclass AliaPay implements IPay {
@Override
public void pay() {
System.out.println("===发起支付宝支付===");
}
}
@Service
publicclass WeixinPay implements IPay {
@Override
public void pay() {
System.out.println("===发起微信支付===");
}
}
@Service
publicclass JingDongPay implements IPay {
@Override
public void pay() {
System.out.println("===发起京东支付===");
}
}
@Service
publicclass PayService {
@Autowired
private AliaPay aliaPay;
@Autowired
private WeixinPay weixinPay;
@Autowired
private JingDongPay jingDongPay;
public void toPay(String code) {
if ("alia".equals(code)) {
aliaPay.pay();
} elseif ("weixin".equals(code)) {
weixinPay.pay();
} elseif ("jingdong".equals(code)) {
jingDongPay.pay();
} else {
System.out.println("找不到支付方式");
}
}
}
PayService类根据不同的code,决定调用用不同的支付类(比如:aliaPay)的pay方法进行支付。
那如果支付方式越来越多,就需要改toPay方法的代码,增加新的if...else判断!!那么代码就会显得无比冗余!!
那我们有啥好的办法可以优化这些代码呢?
我们先来看一下这个案例!!
首先定义一个注解。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public@interface PayCode {
String value();
String name();
}
在所有的支付类上都加上该注解
@PayCode(value = "alia", name = "支付宝支付")
@Service
publicclass AliaPay implements IPay {
@Override
public void pay() {
System.out.println("===发起支付宝支付===");
}
}
@PayCode(value = "weixin", name = "微信支付")
@Service
publicclass WeixinPay implements IPay {
@Override
public void pay() {
System.out.println("===发起微信支付===");
}
}
@PayCode(value = "jingdong", name = "京东支付")
@Service
publicclass JingDongPay implements IPay {
@Override
public void pay() {
System.out.println("===发起京东支付===");
}
}
然后增加最关键的类:
@Service
publicclass PayService2 implements ApplicationListener<ContextRefreshedEvent> {
privatestatic Map<String, IPay> payMap = null;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(PayCode.class);
if (beansWithAnnotation != null) {
payMap = new HashMap<>();
beansWithAnnotation.forEach((key, value) ->{
String bizType = value.getClass().getAnnotation(PayCode.class).value();
payMap.put(bizType, (IPay) value);
});
}
}
public void pay(String code) {
payMap.get(code).pay();
}
}
我们获取打了PayCode注解的类,放到一个map中,map中的key就是PayCode注解中定义的value,跟code参数一致,value是支付类的实例。
这样,每次就可以每次直接通过code获取支付类实例,而不用if...else判断了。
注意:这种方式的code可以没有业务含义,可以是纯数字,只有不重复就行。
那么还有一种方法主要针对code是有业务含义的场景。
@Service
publicclass PayService3 implements ApplicationContextAware {
private ApplicationContext applicationContext;
privatestaticfinal String SUFFIX = "Pay";
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void toPay(String payCode) {
((IPay) applicationContext.getBean(getBeanName(payCode))).pay();
}
public String getBeanName(String payCode) {
return payCode + SUFFIX;
}
}
我们可以看到,aliaPay、weixinPay和jingDongPay,这些支付类bean的名称都是由code和后缀拼接而成!
这就要求支付类取名的时候要特别注意,前面的一段要和code保持一致。
调用的支付类的实例是直接从ApplicationContext
实例中获取的,默认情况下bean
是单例的,放在内存的一个map
中,所以不会有性能问题。
当然实际项目开发中使用if...else判断的场景非常多,上面只是其中2种场景。
下面再列举一下其他常见的场景。
根据不同的数字返回不同的字符串
public String getMessage(int code) {
if (code == 1) {
return"成功";
} elseif (code == -1) {
return"失败";
} elseif (code == -2) {
return"网络超时";
} elseif (code == -3) {
return"参数错误";
}
thrownew RuntimeException("code错误");
}
其实,这种判断没有必要,用一个枚举就可以搞定。
publicenum MessageEnum {
SUCCESS(1, "成功"),
FAIL(-1, "失败"),
TIME_OUT(-2, "网络超时"),
PARAM_ERROR(-3, "参数错误");
privateint code;
private String message;
MessageEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
returnthis.code;
}
public String getMessage() {
returnthis.message;
}
public static MessageEnum getMessageEnum(int code) {
return Arrays.stream(MessageEnum.values()).filter(x -> x.code == code).findFirst().orElse(null);
}
}
再把调用方法稍微调整一下
public String getMessage(int code) {
MessageEnum messageEnum = MessageEnum.getMessageEnum(code);
return messageEnum.getMessage();
}
完美!!!
当然,还有很多其他的场景可以优化if...else,我再这里就不一一介绍了,感兴趣的朋友可以给我留言,一起探讨和研究一下。
最后说一句(求关注!)
如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!
标签:code,String,..,pay,void,别错过,value,else,public From: https://blog.51cto.com/u_16502039/9187057