<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>

          誰能干掉了if else,我就吹他牛逼

          共 3865字,需瀏覽 8分鐘

           ·

          2020-04-10 23:25


          本文公眾號來源:Hollis作者:Hollis本文已收錄至我的GitHub

          我也不用設(shè)計模式

          很多人覺得自己寫的是業(yè)務(wù)代碼,按照邏輯寫下去,再把公用的方法抽出來復(fù)用就可以了,設(shè)計模式根本就沒必要用,更沒必要學(xué)。

          一開始的時候,我也是這么想,直到我遇到。。。

          舉個栗子

          我們先看一個普通的下單攔截接口。

          基本邏輯,參數(shù)安全攔截,次數(shù)攔截,規(guī)則攔截,都通過,返回允許下單,任意一個失敗,返回對應(yīng)的失敗原因。

          多層嵌套if寫法

          我們正常多層嵌套if的寫法

          /**
          ?*?@author?saier
          ?*?@date?2020/3/31?18:03
          ?*/

          public?class?Order?{
          ????public?Message?interrupt1(){
          ????????return?null;
          ????}
          ????public?Message?interrupt2(){
          ????????return?null;
          ????}
          ????public?Message?interrupt3(){
          ????????return?null;
          ????}
          ????public?Message?interrupt4(){
          ????????return?null;
          ????}
          ????public?Message?interrupt5(){
          ????????return?null;
          ????}

          ????public?static?void?main(String[]?args)?{
          ????????Order?order=?new?Order();
          ????????if(order.interrupt1().getResult()?==?1){
          ????????????if(order.interrupt2().getResult()?==?1){
          ????????????????if(order.interrupt3().getResult()?==?1){
          ????????????????????if(order.interrupt4().getResult()?==?1){
          ????????????????????????if(order.interrupt5().getResult()?==?1){
          ????????????????????????????System.out.println("success");
          ????????????????????????}
          ????????????????????}
          ????????????????}
          ????????????}
          ????????}

          ????}
          }

          @Data
          class?Message?{
          ????private?int?result;
          ????private?String?msg;
          }

          異常處理邏輯

          或者有些利用異常做邏輯,代碼會簡單一點(diǎn)

          /**
          ?*?@author?saier
          ?*?@date?2020/3/31?18:03
          ?*/

          public?class?Order2?{
          ????public?void?interrupt1(){

          ????}
          ????public?void?interrupt2(){

          ????}
          ????public?void?interrupt3(){
          ????????//失敗
          ????????throw?new?RuntimeException();
          ????}
          ????public?void?interrupt4(){
          ????????//失敗
          ????????throw?new?RuntimeException();
          ????}
          ????public?void?interrupt5(){
          ????????//失敗
          ????????throw?new?RuntimeException();
          ????}

          ????public?static?void?main(String[]?args)?{
          ????????Order2?order2=?new?Order2();
          ????????try{
          ????????????order2.interrupt1();
          ????????????order2.interrupt2();
          ????????????order2.interrupt3();
          ????????????order2.interrupt4();
          ????????????order2.interrupt5();
          ????????????System.out.println("success");
          ????????}catch?(RuntimeException?e){
          ????????????System.out.println("fail");
          ????????}

          ????}
          }

          一開始,我就直接使用異常來做邏輯。但后續(xù)邏輯越來越復(fù)雜之后,也會出現(xiàn)一些問題。例如異常只能返回異常信息,不能返回更多的字段信息。

          后面也留意到,異常做邏輯,在阿里規(guī)范是禁止的。

          阿里代碼規(guī)范 :
          【強(qiáng)制】異常不要用來做流程控制,條件控制。
          說明:異常設(shè)計的初衷是解決程序運(yùn)行中的各種意外情況,且異常的處理效率比條件判斷方式要低很多。

          更重要的是,代碼可讀性太差了,隨時一個方法的異常拋出來,還要考慮代碼本身的異常。

          沒更好的辦法,只能考慮設(shè)計模式了

          怎么改,會使代碼的可讀性高,擴(kuò)展性好?

          在同事的提醒下,突然想起了設(shè)計模式!

          我們希望達(dá)到的目的

          1. 代碼沒有這么多if else嵌套,可讀性高
          2. 如果新增新的攔截邏輯簡單方便,不影響原本的邏輯,擴(kuò)展性好
          3. 可以很方便地調(diào)換攔截邏輯順序,低耦合

          責(zé)任鏈模式

          在這種場景下,非常適合責(zé)任鏈模式。(什么場景使用什么設(shè)計模式,這就需要平時有積累,知道各種設(shè)計模式的基本使用)

          責(zé)任鏈,顧名思義,就是用來處理相關(guān)事務(wù)責(zé)任的一條執(zhí)行鏈,執(zhí)行鏈上有多個節(jié)點(diǎn),每個節(jié)點(diǎn)都有機(jī)會(條件匹配)處理請求事務(wù),如果某個節(jié)點(diǎn)處理完了就可以根據(jù)實(shí)際業(yè)務(wù)需求傳遞給下一個節(jié)點(diǎn)繼續(xù)處理或者返回處理完畢。

          首先,建立過濾器的抽象類

          public?abstract?class?AbstractFilter?{

          ????private?AbstractFilter?nextFilter;

          ????/**
          ?????*?責(zé)任鏈的下一個元素
          ?????*/

          ????public?void?setNextFilter(AbstractFilter?nextFilter){
          ????????this.nextFilter?=?nextFilter;
          ????}


          ????public?AbstractFilter?getLastFilter(){
          ????????if(this.nextFilter?!=?null){
          ????????????return?this.nextFilter.getLastFilter();
          ????????}else{
          ????????????return?this;
          ????????}
          ????}

          ????public?void?filter(FilterRequest?filterRequest,?Response?response){
          ????????doFilter(filterRequest,response);
          ????????if(response.isFilterNext()?&&?nextFilter?!=?null){
          ????????????nextFilter.filter(filterRequest,response);
          ????????}
          ????}

          ????/**
          ?????*?具體攔截邏輯
          ?????*/

          ????public?abstract?void?doFilter(FilterRequest?filterRequest,?Response?response);

          ????/**
          ?????*?根據(jù)攔截結(jié)果做處理
          ?????*/

          ????public?void?exec(FilterRequest?filterRequest,?Response?response){
          ????}
          }

          過濾器的實(shí)現(xiàn)類

          @Component
          @Order(5)
          public?class?CheckParamFilter1?extends?AbstractFilter?{
          ????@Override
          ????public?void?doFilter(FilterRequest?filterRequest,?Response?response)?{

          ????}
          }

          @Component
          @Order(10)
          public?class?CheckParamFilter2?extends?AbstractFilter?{
          ????@Override
          ????public?void?doFilter(FilterRequest?filterRequest,?Response?response)?{

          ????}
          }

          使用Order注解,確定過濾器的順序,后續(xù)在spring注入的時候,會有奇效

          //利用spring的自動注入機(jī)制
          @Autowired
          List?abstractFilterList;

          private?AbstractFilter?firstFilter;

          //spring注入后自動執(zhí)行
          @PostConstruct
          public?void?initializeChainFilter(){
          ????//把所有調(diào)用的邏輯注入到責(zé)任鏈,按照Order排序,越小優(yōu)先級越高
          ????for(int?i?=?0;i????????if(i?==?0){
          ????????????firstFilter?=?abstractFilterList.get(i);
          ????????}else{
          ????????????firstFilter.getLastFilter().setNextFilter(abstractFilterList.get(i));
          ????????}
          ????}
          }

          //直接使用
          public?Response?exec(){
          ????firstFilter.filter(filterRequest,?response);
          ????return?response;
          }

          使用設(shè)計模式的好處

          看下使用責(zé)任鏈模式后,有什么好處!

          1. 新增攔截邏輯,只需要再實(shí)現(xiàn)一個AbstractFilter類即可
          2. 修改攔截順序,只需要修改Order注解的大小,越小,優(yōu)先級越高
          3. 代碼清晰,所有處理邏輯下沉到實(shí)現(xiàn)類中

          使用設(shè)計模式的缺點(diǎn)

          做到了低耦合,高擴(kuò)展。但也帶來了一些不好的地方

          1. 邏輯更復(fù)雜,用了鏈?zhǔn)降葦?shù)據(jù)結(jié)構(gòu),要注意單例的問題,不能重復(fù)使用
          2. 類數(shù)量激增,一個攔截器就一個類

          最后小結(jié)一下

          不是什么地方都適合使用設(shè)計模式,如果邏輯簡單,你硬要使用設(shè)計模式,只會帶來結(jié)構(gòu)上的復(fù)雜,大家可以按照大家的業(yè)務(wù)場景來使用。


          戳:百萬字長文帶你學(xué)習(xí)「Java」

          掃碼或者微信搜Java3y?免費(fèi)領(lǐng)取原創(chuàng)思維導(dǎo)圖、精美PDF。在公眾號回復(fù)「888」領(lǐng)取,PDF內(nèi)容純手打有任何不懂歡迎來問我。

          4532936926825c26e53ca77358153f4d.webp

          a2b3c9fd21f20a07f4c2eda8f69126e2.webp


          303065f5f221c5170a8db72cc3cdef2b.webp

          007f0e40b64f6de37590201e95a2d003.webp

          007f0e40b64f6de37590201e95a2d003.webp

          瀏覽 32
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  肉搏丝袜一区 | 97一区二区三区 | www.日逼网站 | 91CM229 跳蛋购物 突袭做爱 1080P - 美竹玲 | 日批在线视频 |