优化if…else…语句

写代码的时候经常遇到这样的场景:根据某个字段值来进行不同的逻辑处理。例如,不同的会员等级在购物时有不同的折扣力度。如果会员的等级很多,那么代码中与之相关的if...elseif...else...会特别长,而且每新增一种等级时需要修改原先的代码。可以用策略模式来优化,消除这种场景下的if...elseif...else...,使代码看起来更优雅。

优化if...else...语句

首先,定义一个接口

/**  * 会员服务  */ public interface VipService {     void handle(); }

然后,定义实现类

/**  * 白银会员  */ public class SilverVipService implements VipService {     @Override     public void handle() {         System.out.println("白银");     } }  /**  * 黄金会员  */ public class GoldVipService implements VipService {     @Override     public void handle() {         System.out.println("黄金");     } }

最后,定义一个工厂类,目的是当传入一个会员等级后,返回其对应的处理类

public class VipServiceFactory {     private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();      public static void register(String type, VipService service) {         vipMap.put(type, service);     }      public static VipService getService(String type) {         return vipMap.get(type);     } }

为了建立会员等级和与之对应的处理类之间的映射关系,这里通常可以有这么几种处理方式:

方式一:实现类手动注册

可以实现InitializingBean接口,或者在某个方法上加@PostConstruct注解

import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component;  /**  * 白银会员  */ @Component public class SilverVipService implements VipService, InitializingBean {     @Override     public void handle() {         System.out.println("白银");     }      @Override     public void afterPropertiesSet() throws Exception {         VipServiceFactory.register("silver", this);     } }  /**  * 黄金会员  */ @Component public class GoldVipService implements VipService, InitializingBean {     @Override     public void handle() {         System.out.println("黄金");     }      @Override     public void afterPropertiesSet() throws Exception {         VipServiceFactory.register("gold", this);     } }

方式二:从Spring容器中直接获取Bean

public interface VipService {     void handle();     String getType(); }  /**  * 白银会员  */ @Component public class SilverVipService implements VipService {     @Override     public void handle() {         System.out.println("白银");     }     @Override     public String getType() {         return "silver";     } }  /**  * 黄金会员  */ @Component public class GoldVipService implements VipService {     @Override     public void handle() {         System.out.println("黄金");     }     @Override     public String getType() {         return "gold";     } }  /**  * 上下文  */ @Component public class VipServiceFactory implements ApplicationContextAware {     private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();      @Override     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {         Map<String, VipService> map = applicationContext.getBeansOfType(VipService.class);         map.values().forEach(service -> vipMap.put(service.getType(), service));     }      public static VipService getService(String type) {         return vipMap.get(type);     } }  /**  * 测试  */ @SpringBootTest class DemoApplicationTests {     @Test     void contextLoads() {         VipServiceFactory.getService("silver").handle();     } }

方式三:反射+自定义注解

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MemberLevel {     String value(); }  @MemberLevel("silver") @Component public class SilverVipService implements VipService {     @Override     public void handle() {         System.out.println("白银");     } }  @MemberLevel("gold") @Component public class GoldVipService implements VipService {     @Override     public void handle() {         System.out.println("黄金");     } }  /**  * 上下文  */ @Component public class VipServiceFactory implements ApplicationContextAware {     private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();      @Override     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { //        Map<String, VipService> map = applicationContext.getBeansOfType(VipService.class);         Map<String, Object> map = applicationContext.getBeansWithAnnotation(MemberLevel.class);         for (Object bean : map.values()) {             if (bean instanceof VipService) {                 String type = bean.getClass().getAnnotation(MemberLevel.class).value();                 vipMap.put(type, (VipService) bean);             }         }     }      public static VipService getService(String type) {         return vipMap.get(type);     } }

完整示例代码

/**  * 结算业务种类  * @Author: ChengJianSheng  * @Date: 2023/1/16  */ @Getter public enum SettlementBusiType {     RE1011("RE1011", "转贴现"),     RE4011("RE4011", "买断式贴现"),     RE4021("RE4021", "回购式贴现"),     RE4022("RE4022", "回购式贴现赎回"); //    ......      private String code;     private String name;      SettlementBusiType(String code, String name) {         this.code = code;         this.name = name;     } }   /**  * 结算处理器  * @Author: ChengJianSheng  * @Date: 2023/1/16  */ public interface SettlementHandler {     /**      * 清算      */     void handle();      /**      * 获取业务种类      */     SettlementBusiType getBusiType(); }   /**  * 转贴现结算处理  */ @Component public class RediscountSettlementHandler implements SettlementHandler {     @Override     public void handle() {         System.out.println("转贴现");     }      @Override     public SettlementBusiType getBusiType() {         return SettlementBusiType.RE1011;     } }   /**  * 买断式贴现结算处理  */ @Component public class BuyoutDiscountSettlementHandler implements SettlementHandler {     @Override     public void handle() {         System.out.println("买断式贴现");     }      @Override     public SettlementBusiType getBusiType() {         return SettlementBusiType.RE4011;     } }   /**  * 默认处理器  * @Author: ChengJianSheng  * @Date: 2023/1/16  */ @Component public class DefaultSettlementHandler implements /*SettlementHandler,*/ ApplicationContextAware {     private static Map<SettlementBusiType, SettlementHandler> allHandlerMap = new ConcurrentHashMap<>();      public static SettlementHandler getHandler(SettlementBusiType busiType) {         return allHandlerMap.get(busiType);     }      @Override     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {         Map<String, SettlementHandler> map = applicationContext.getBeansOfType(SettlementHandler.class);         map.values().forEach(e -> allHandlerMap.put(e.getBusiType(), e));     } }   @SpringBootTest class Demo2023ApplicationTests {     @Test     void contextLoads() {         // 收到结算结果通知,根据业务种类进行结算处理         SettlementHandler handler = DefaultSettlementHandler.getHandler(SettlementBusiType.RE1011);         if (null != handler) {             handler.handle();         }     } }

 

发表评论

相关文章