1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        在 Spring Boot 中,如何干掉 if else

        共 4073字,需瀏覽 9分鐘

         ·

        2022-01-10 18:29

        不點(diǎn)藍(lán)字關(guān)注,我們哪來(lái)故事?




        ?正文如下?

        來(lái)源:https://blog.csdn.net/hncu1306602liuqiang


        看到crossover Jie的文章《利用策略模式優(yōu)化過(guò)多if else 代碼》后受到啟發(fā),可以利用策略模式簡(jiǎn)化過(guò)多的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())) { //促銷訂單處理 } //未來(lái)訂單類型增加 }

        }//實(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("該類型沒(méi)有在枚舉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); }

        /* * 通過(guò)父類+注解找到實(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("該注解沒(méi)有寫入值 :" + code); } //注解值是否與code相等 if (code.equals(orderTypeHandlerAnno.value().getCode())) { return t; } } throw new RuntimeException("通過(guò)code沒(méi)有找到該注解對(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ù)人員編寫代碼。


        你好,來(lái)交個(gè)朋友 ~


        往期推薦

        一個(gè)程序員北漂的真實(shí)工作和生活

        2021 互聯(lián)網(wǎng)公司時(shí)薪排行榜出爐!

        盡量不要內(nèi)卷同事,都不容易,他的今天也許就是你的明天...

        阿里二面:GET 請(qǐng)求能傳圖片嗎?

        你覺(jué)得 JSP 如何呢?是否應(yīng)該被淘汰呢?


        //////?END?//////
        ↓ 點(diǎn)擊下方關(guān)注,看更多架構(gòu)分享?↓

        ↓ 或加泥瓦匠微信,交流更多技術(shù)?↓

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

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲女人操逼 | 骚货网站| www.91 | 久久夜久久 | 一区二区三区四区五区在线 | 韩国三级高潮做爰 | 天操中文字幕在线观看 | 国产另类st变态重口 | 人妖99视频在线 | 成人毛片18女人免费视频 |