<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

          共 3267字,需瀏覽 7分鐘

           ·

          2021-11-23 21:19

          相關(guān)閱讀

          300本計算機編程的經(jīng)典書籍下載

          AI全套:Python3+TensorFlow打造人臉識別智能小程序

          最新人工智能資料-Google工程師親授 Tensorflow-入門到進階

          Java架構(gòu)全階段七期完整

          黑馬頭條項目 - Java Springboot2.0(視頻、資料、代碼和講義)14天完整版

          Spring核心編程思想


          原文鏈接:https://blog.csdn.net/hncu1306602liuqiang

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

          需求

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

          項目結(jié)構(gòu)

          訂單實體

          /**
          ?*?訂單實體
          ?*/

          public?class?OrderDTO?{
          ????private?String?code;
          ????private?BigDecimal?price;

          ????/*
          ?????*?訂單類型:
          ?????* 1:普通訂單
          ?????* 2:團購訂單
          ?????* 3:促銷訂單
          ?????*/

          ????private?String?type;
          //getter,setter自己實現(xiàn)
          }

          service接口

          /**
          ?*?訂單處理
          ?*/

          public?interface?IOrderService?{

          ????/**
          ?????*?根據(jù)訂單的不同類型做出不同的處理
          ?????*
          ?????*?@param?dto?訂單實體
          ?????*?@return?為了簡單,返回字符串
          ?????*/

          ????String?orderHandler(OrderDTO?dto);

          }
          //實現(xiàn)類1
          @Component
          public?class?OrderServiceImpl?implements?IOrderService?{

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

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

          ????@Override
          ????public?String?orderHandler(OrderDTO?dto)?{
          ????????/*
          ?????????* 1:使用if..else實現(xiàn)
          ?????????* 2:使用策略模式實現(xiàn)
          ?????????*/

          ????????AOrderTypeHandler?instance?=?handlerContext.getInstance(dto.getType());
          ????????return?instance.handler(dto);
          ????}

          }

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

          HandlerContext和HandlerProccessor
          /**
          ?*?訂單策略模式環(huán)境
          ?*?這個類的注入由HandlerProccessor實現(xiàn)
          ?*/

          public?class?HandlerContext?{
          ????private?Map?handlerMap;

          ????/**
          ?????*?構(gòu)造傳參不能直接使用注解掃入
          ?????*/

          ????public?HandlerContext(Map?handlerMap)?{
          ????????this.handlerMap?=?handlerMap;
          ????}

          ????/**
          ?????*?獲得實例
          ?????*
          ?????*?@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中定義,請定義:"?+?type);
          ????????}
          ????????return?clazz;
          ????}

          }
          /**
          ?*?策略模式,處理type與實現(xiàn)類的映射關(guān)系
          ?*/

          @Component
          public?class?HandlerProccessor?implements?BeanFactoryPostProcessor?{

          ????/**
          ?????*?掃描@OrderTypeHandlerAnno注解,初始化HandlerContext,將其注冊到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);
          ????}

          ????/*
          ?????*?通過父類+注解找到實體類
          ?????*/

          ????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沒有找到該注解對應(yīng)的實體類?:"?+?code);
          ????}

          }

          父抽象類+注解+枚舉

          /**
          ?*?訂單類型處理定義
          ?*?使用抽象類,那么子類就只有一個繼承了
          ?*/

          public?abstract?class?AOrderTypeHandler?{

          ????/**
          ?????*?一個訂單類型做一件事
          ?????*
          ?????*?@param?dto?訂單實體
          ?????*?@return?為了簡單,返回字符串
          ?????*/

          ????abstract?public?String?handler(OrderDTO?dto);

          }

          /**
          ?*?訂單類型注解
          ?*?使用方式:
          ?* 1:普通訂單?@OrderTypeHandlerAnno("1")
          ?* 2:團購訂單?@OrderTypeHandlerAnno("2")
          ?* 3:促銷訂單?@OrderTypeHandlerAnno("3")
          ?*/

          @Target({ElementType.TYPE})
          @Retention(RetentionPolicy.RUNTIME)
          @Documented
          @Inherited
          public?@interface?OrderTypeHandlerAnno?{

          ????OrderTypeEnum?value();

          }

          /**
          ?*?訂單類型枚舉
          ?*/

          public?enum?OrderTypeEnum?{
          ????Normal("1",?"普通"),
          ????Group("2",?"團隊"),
          ????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ù)人員實現(xiàn)類

          //業(yè)務(wù)代碼
          /**
          ?*?普通訂單處理
          ?*/

          @Component
          @OrderTypeHandlerAnno(OrderTypeEnum.Normal)
          public?class?NormalOrderHandler?extends?AOrderTypeHandler?{

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

          }

          /**
          ?*?團隊訂單處理
          ?*/

          @Component
          @OrderTypeHandlerAnno(OrderTypeEnum.Group)
          public?class?GroupOrderHandler?extends?AOrderTypeHandler?{

          ????@Override
          ????public?String?handler(OrderDTO?dto)?{
          ????????return?"處理團隊訂單";
          ????}

          }

          /**
          ?*?促銷訂單處理
          ?*/

          @Component
          @OrderTypeHandlerAnno(OrderTypeEnum.Promotion)
          public?class?PromotionOrderHandler?extends?AOrderTypeHandler?{

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

          }

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

          如果類型不存在


          ????4.0.0????????????org.springframework.boot????????spring-boot-starter-parent????????2.2.1.RELEASE?????????????????com.kayak????study-design????0.0.1-SNAPSHOT????study-design????Demo?project?for?Spring?Boot????????????1.8????????????????????????????org.springframework.boot????????????spring-boot-starter-web????????????????????????????org.springframework.boot????????????spring-boot-starter-test????????????test????????????????????????????????????????????????org.junit.vintage????????????????????junit-vintage-engine????????????????????????????????????????????????????????????????????????????????org.springframework.boot????????????????spring-boot-maven-plugin????????????????????????" tab="innerlink" data-linktype="2" wah-hotarea="click" style="outline: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">controller

          /**
          ?*?策略模式
          ?*/

          @RestController
          public?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é):

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

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

          這個就是個人筆記,不喜勿噴。

          全棧架構(gòu)社區(qū)交流群

          ?「全棧架構(gòu)社區(qū)」建立了讀者架構(gòu)師交流群,大家可以添加小編微信進行加群。歡迎有想法、樂于分享的朋友們一起交流學(xué)習(xí)。

          掃描添加好友邀你進架構(gòu)師群,加我時注明姓名+公司+職位】

          看完本文有收獲?請轉(zhuǎn)發(fā)分享給更多人


          往期資源:


          Flutter 移動應(yīng)用開發(fā)實戰(zhàn) 視頻(開發(fā)你自己的抖音APP)
          Java面試進階訓(xùn)練營 第2季(分布式篇)
          Java高級 - 分布式系統(tǒng)開發(fā)技術(shù)視頻
          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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 亚洲专区在线播放 | 成人AV一区二区三区四区 | 欧美日韩一级免费 |