<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在 Spring Boot 中,如何干掉 if else

          共 4111字,需瀏覽 9分鐘

           ·

          2021-11-04 19:22

          程序員的成長(zhǎng)之路
          互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享?
          關(guān)注


          閱讀本文大概需要 5?分鐘。

          來自:https://blog.csdn.net/hncu1306602liuqiang

          看到crossover Jie的文章《利用策略模式優(yōu)化過多if else 代碼》后受到啟發(fā),可以利用策略模式簡(jiǎn)化過多的if else代碼。


          # 需求


          這里虛擬一個(gè)業(yè)務(wù)需求,讓大家容易理解。假設(shè)有一個(gè)訂單系統(tǒng),里面的一個(gè)概念是根據(jù)訂單的不同類型做出不同的處理。

          # 項(xiàng)目結(jié)構(gòu)



          訂單實(shí)體

          /** * 訂單實(shí)體 */public class OrderDTO { private String code; private BigDecimal price;

          /* * 訂單類型: * 1:普通訂單 * 2:團(tuán)購(gòu)訂單 * 3:促銷訂單 */ private String type;//getter,setter自己實(shí)現(xiàn)}

          service接口

          /** * 訂單處理 */public interface IOrderService {

          /** * 根據(jù)訂單的不同類型做出不同的處理 * * @param dto 訂單實(shí)體 * @return 為了簡(jiǎn)單,返回字符串 */ String orderHandler(OrderDTO dto);

          }//實(shí)現(xiàn)類1@Componentpublic class OrderServiceImpl implements IOrderService {

          @Override public String orderHandler(OrderDTO dto) { if ("1".equals(dto.getType())) { //普通訂單處理 } else if ("2".equals(dto.getType())) { //團(tuán)購(gòu)訂單處理 } else if ("3".equals(dto.getType())) { //促銷訂單處理 } //未來訂單類型增加 }

          }//實(shí)現(xiàn)類二@Componentpublic class OrderServiceImpl implements IOrderService { //使用策略模式實(shí)現(xiàn) @Autowired private HandlerContext handlerContext;

          @Override public String orderHandler(OrderDTO dto) { /* * 1:使用if..else實(shí)現(xiàn) * 2:使用策略模式實(shí)現(xiàn) */ AOrderTypeHandler instance = handlerContext.getInstance(dto.getType()); return instance.handler(dto); }

          }

          利用策略模式只需要2行代碼就可以搞定(也可以用工廠)

          HandlerContext和HandlerProccessor
          /** * 訂單策略模式環(huán)境 * 這個(gè)類的注入由HandlerProccessor實(shí)現(xiàn) */public class HandlerContext { private Map<String, AOrderTypeHandler> handlerMap;

          /** * 構(gòu)造傳參不能直接使用注解掃入 */ public HandlerContext(Map<String, AOrderTypeHandler> handlerMap) { this.handlerMap = handlerMap; }

          /** * 獲得實(shí)例 * * @param type * @return */ public AOrderTypeHandler getInstance(String type) { if (type == null) { throw new IllegalArgumentException("type參數(shù)不能為空"); } AOrderTypeHandler clazz = handlerMap.get(type); if (clazz == null) { throw new IllegalArgumentException("該類型沒有在枚舉OrderTypeHandlerAnno中定義,請(qǐng)定義:" + type); } return clazz; }

          }
          /** * 策略模式,處理type與實(shí)現(xiàn)類的映射關(guān)系 */@Componentpublic class HandlerProccessor implements BeanFactoryPostProcessor {    /**     * 掃描@OrderTypeHandlerAnno注解,初始化HandlerContext,將其注冊(cè)到spring容器     *     * @param beanFactory bean工廠     * @throws BeansException     */    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        Map handlerMap = new HashMap<>();        for (OrderTypeEnum temp : OrderTypeEnum.values()) {            AOrderTypeHandler beanInstacle = getBeansWithAnnotation(beanFactory, AOrderTypeHandler.class, OrderTypeHandlerAnno.class, temp.getCode());            handlerMap.put(temp.getCode(), beanInstacle);        }        HandlerContext context = new HandlerContext(handlerMap);        //單例注入        beanFactory.registerSingleton(HandlerContext.class.getName(), context);    }    /*     * 通過父類+注解找到實(shí)體類     */    private  T getBeansWithAnnotation(ConfigurableListableBeanFactory beanFactory, Class manager, Class annotation, String code) throws BeansException {        if (ObjectUtils.isEmpty(code)) {            throw new RuntimeException("code is null ");        }        Collection tCollection = beanFactory.getBeansOfType(manager).values();        for (T t : tCollection) {            OrderTypeHandlerAnno orderTypeHandlerAnno = t.getClass().getAnnotation(annotation);            if (ObjectUtils.isEmpty(orderTypeHandlerAnno)) {                throw new RuntimeException("該注解沒有寫入值 :" + code);            }            //注解值是否與code相等            if (code.equals(orderTypeHandlerAnno.value().getCode())) {                return t;            }        }        throw new RuntimeException("通過code沒有找到該注解對(duì)應(yīng)的實(shí)體類 :" + code);    }}

          父抽象類+注解+枚舉

          /** * 訂單類型處理定義 * 使用抽象類,那么子類就只有一個(gè)繼承了 */public abstract class AOrderTypeHandler {

          /** * 一個(gè)訂單類型做一件事 * * @param dto 訂單實(shí)體 * @return 為了簡(jiǎn)單,返回字符串 */ abstract public String handler(OrderDTO dto);

          }

          /** * 訂單類型注解 * 使用方式: * 1:普通訂單 @OrderTypeHandlerAnno("1") * 2:團(tuán)購(gòu)訂單 @OrderTypeHandlerAnno("2") * 3:促銷訂單 @OrderTypeHandlerAnno("3") */@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface OrderTypeHandlerAnno {

          OrderTypeEnum value();

          }

          /** * 訂單類型枚舉 */public enum OrderTypeEnum { Normal("1", "普通"), Group("2", "團(tuán)隊(duì)"), Promotion("3", "促銷");

          private String code; //代碼 private String name; //名稱,描述

          OrderTypeEnum(String code, String name) { this.code = code; this.name = name; }

          public String getCode() { return code; }

          public void setCode(String code) { this.code = code; }

          public String getName() { return name; }

          public void setName(String name) { this.name = name; }

          /** * 根據(jù)code屬性獲取name屬性 * * @param code * @return */ public static String getNameByCode(String code) { for (OrderTypeEnum temp : OrderTypeEnum.values()) { if (temp.getCode().equals(code)) { return temp.getName(); } } return null; }

          }

          業(yè)務(wù)人員實(shí)現(xiàn)類
          //業(yè)務(wù)代碼/** * 普通訂單處理 */@Component@OrderTypeHandlerAnno(OrderTypeEnum.Normal)public class NormalOrderHandler extends AOrderTypeHandler {

          @Override public String handler(OrderDTO dto) { return "處理普通訂單"; }

          }

          /** * 團(tuán)隊(duì)訂單處理 */@Component@OrderTypeHandlerAnno(OrderTypeEnum.Group)public class GroupOrderHandler extends AOrderTypeHandler {

          @Override public String handler(OrderDTO dto) { return "處理團(tuán)隊(duì)訂單"; }

          }

          /** * 促銷訂單處理 */@Component@OrderTypeHandlerAnno(OrderTypeEnum.Promotion)public class PromotionOrderHandler extends AOrderTypeHandler {

          @Override public String handler(OrderDTO dto) { return "處理促銷訂單"; }

          }

          測(cè)試結(jié)果(使用chrome瀏覽器測(cè)試結(jié)果)


          如果類型不存在


          controller

          /** * 策略模式 */@RestControllerpublic class StrategyController { @Resource(name = "orderServiceImpl") private IOrderService orderService;

          @GetMapping("/api/order") @ResponseBody public String orderSave(OrderDTO dto) { String str = orderService.orderHandler(dto); return "{\"status\":1,\"msg\":\"保存成功\",\"data\":\"" + str + "\"}"; }

          }pom.xml文檔

          "1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0modelVersion> <parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-parentartifactId> <version>2.2.1.RELEASEversion> <relativePath/> parent> <groupId>com.kayakgroupId> <artifactId>study-designartifactId> <version>0.0.1-SNAPSHOTversion> <name>study-designname> <description>Demo project for Spring Bootdescription>

          <properties> <java.version>1.8java.version> properties>

          <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency>

          <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> <exclusions> <exclusion> <groupId>org.junit.vintagegroupId> <artifactId>junit-vintage-engineartifactId> exclusion> exclusions> dependency> dependencies>

          <build> <plugins> <plugin> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-maven-pluginartifactId> plugin> plugins> build>

          project>

          # 總結(jié):


          利用策略模式可以簡(jiǎn)化復(fù)雜的if else代碼,方便維護(hù),而利用自定義注解和自注冊(cè)的方式,可以方便應(yīng)對(duì)需求的變更。

          主要是方便了業(yè)務(wù)人員編寫代碼。

          這個(gè)就是個(gè)人筆記,不喜勿噴。

          推薦閱讀:

          支付寶員工因績(jī)效3.25B被辭退,員工告上法院,結(jié)果來了!

          SQL去重的三種方法匯總

          最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點(diǎn)個(gè)「在看」,點(diǎn)擊上方小卡片,進(jìn)入公眾號(hào)后回復(fù)「面試題」領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          朕已閱?

          瀏覽 70
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色一级免费片 | 大香蕉天天 | 毛片三区| 亚洲国产成人Av片在线观看 | 日本午夜福利 |