精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

干掉項目中雜亂的 if-else,試試狀態模式,這才是優雅的實現方式!

開發 后端
原來以為寫一個簡單的類型翻譯器花不了太多時間,可是真做起來,才發現要注意的點太多了。

 IF-ELSE 方式

原來以為寫一個簡單的類型翻譯器花不了太多時間,可是真做起來,才發現要注意的點太多了。

首先是處理容器的開啟和閉合,這就需要使用棧來保存預期的下一個字符類型,再對比棧頂字符類型和當前處理字符,決定解析的結果。

還要注意類型嵌套的情況下,內層嵌套的容器作為外層容器的元素被解析完成時,需要修改外層容器的預期字符。而且 Map 作為一種相對 Set 和 List 比較特殊的容器,還要處理它的左右元素。同時還不能忘記處理各種異常,如未知字符、容器內是原始類型、容器未正確閉合等。

而這些邏輯混雜在一塊就更添復雜度了,通常是一遍代碼寫下來挺順暢,找幾個特殊的 case 一驗證,往往就有沒有考慮到的點,你以為解決了這個點就好了,殊不知這個問題點的解決方案又引起了另一個問題。

最終修修補補好多次,終于把代碼寫完了,連優化的想法都沒了,擔心又引入新的問題。更多 Java 核心技術教程:https://github.com/javastacks/javastack,一起來學習吧。

最終的偽代碼如下: 

  1. public String parseToFullType() throws IllegalStateException {  
  2.     StringBuilder sb = new StringBuilder();  
  3.     for (; ; this.scanner.next()) {  
  4.         Character currentChar = scanner.current();  
  5.         if (currentChar == '\uFFFF') {  
  6.             return sb.toString();  
  7.         }  
  8.         if (isCollection()) {  
  9.             if (CollectionEnd()) {  
  10.                 dealCollectionEleEnd();  
  11.             }else {  
  12.                 throw new IllegalStateException("unexpected char '" + currentChar + "' at position " + scanner.getIndex());  
  13.             }  
  14.         } else if (isWrapperType()) {  
  15.             dealSingleEleEnd();  
  16.         } else if (parseStart()) {  
  17.             if (collectionStart()) {  
  18.                 putCollecitonExpectEle()  
  19.             }  
  20.         } else {  
  21.             throw new IllegalStateException("unknown char '" + currentChar + "' at position " + scanner.getIndex());  
  22.         }  
  23.     }    

狀態機方式

是不是看起來非常亂,這還沒有列出各個方法里的條件判斷語句呢。這么多邏輯混雜,造成的問題就是很難改動,因為你不知道改動會影響哪些其他邏輯。

面對這種問題,當然有一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結,就是狀態機。

狀態機

有限狀態機(finite-state machine,縮寫:FSM)又稱有限狀態自動機(finite-state automation,縮寫:FSA),簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學計算模型。

像我們生活中在公路上駕駛汽車就像在維護一個狀態機,遇到紅燈就停車喝口水,紅燈過后再繼續行車,遇到了黃燈就要減速慢行。而實現狀態機前要首先明確四個主體:

  •  狀態 State:狀態是一個系統在其生命周期的某一刻時的運行狀態,如駕車的例子中狀態就包括 正常速度行駛、停車和低速行駛三種狀態。
  •  事件 Event:事件就是某一時刻施加于系統的某個信號,在上面的例子中事件是指紅燈、綠燈和黃燈。所有的狀態變化都要依賴事件,但事件也可能導致狀態不發生變化,如正常行駛中遇到綠燈就不用做什么反應。
  •  變換 Transition:變換是在事件發生之后系統要做出的狀態變化,如上面例子中的減速、停車或加速。
  •  動作 Action:動作是同樣是事件發生之后系統做出的反應,不同的是,動作不會改變系統狀態,像駕車遇到紅燈停車后,喝水這個動作沒有對系統狀態造成影響。

將狀態機的四種要素提取之后,就可以很簡單地將狀態和事件進行解耦了。

狀態拆分

還是拿我的這個需求來分析,先畫出狀態變化圖從整體上把握狀態間的關系。

通過上面的圖一步步拆解狀態機:

    1. 首先是確定狀態,我定義了 Start/SetStart/SetEle/ListStart/ListEel/MapStart/MapLeft/MapRight 八種基礎狀態,由于一次只解析一個類型,容器閉合就代表著解析結束,所以沒有對各個容器設置結束狀態。又因為有狀態嵌套的存在,而一個狀態沒法表達狀態機的準確狀態,需要使用棧來存儲整體的解析狀態,我使用這個棧為空來代表 End 狀態,又省略了一個狀態。

    2. 再拆分事件,事件是掃描到的每一個字符,由于字符種類較多,而像 integer 和 double、String 和 Long 的處理又沒有什么區別,我將事件類型抽象為 包裝類型元素(WRAPPED_ELE),原始類型元素(PRIMITIVE_ELE),MAP、List 和 Set 五種。

    3. 變幻和動作都是事件發生后系統的反應,在我的需要里需要轉變解析狀態,并將結構結果保存起來。這里我將它們整體抽象為一個事件處理器接口,如: 

  1. public interface StateHandler {  
  2.     /**  
  3.      * @param event 要處理的事件  
  4.      * @param states 系統整體狀態  
  5.      * @param result 解析的結果  
  6.      */  
  7.     void handle(Event event, Stack<State> states, StringBuilder result);  

代碼示例

將狀態機的各個要素都抽出來之后,再分別完善每個 StateHandler 的處理邏輯就行,這部分就非常簡單了,下面是 MapLeftHandler 的詳情。 

  1. public class MapLeftHandler implements StateHandler {  
  2.     @Override  
  3.     public void handle(Event event, Stack<State> states, StringBuilder result) {  
  4.         // 這里是核心的 Action,將單步解析結果放到最終結果內  
  5.         result.append(",");  
  6.         result.append(event.getParsedVal());  
  7.         // 狀態機的典型處理方式,處理各種事件發生在當前狀態時的邏輯  
  8.         switch (event.getEventType()) {  
  9.             case MAP:  
  10.                 states.push(State.MAP_START);  
  11.                 break;  
  12.             case SET:  
  13.                 states.push(State.SET_START);  
  14.                 break;  
  15.             case LIST:  
  16.                 states.push(State.LIST_START);  
  17.                 break;  
  18.             case WRAPPED_ELE:  
  19.                 // 使用 pop 或 push 修改棧頂狀態來修改解析器的整體狀態  
  20.                 states.pop();  
  21.                 states.push(State.MAP_RIGHT);  
  22.                 break;  
  23.             case PRIMITIVE_ELE:  
  24.                 // 當前狀態不能接受的事件類型要拋異常中斷  
  25.                 throw new IllegalStateException("unexpected primitive char '" + event.getCharacter() + "' at position " + event.getIndex());  
  26.             default:  
  27.         }  
  28.     }  

主類內的代碼如下: 

  1. public static String parseToFullType(String shortenType) throws IllegalStateException {  
  2.     StringBuilder result = new StringBuilder();  
  3.     StringCharacterIterator scanner = new StringCharacterIterator(shortenType);  
  4.     Stack<State> states = new Stack<>();  
  5.     states.push(State.START);  
  6.     for (; ; scanner.next()) { 
  7.         char currentChar = scanner.current();  
  8.         if (currentChar == '\uFFFF') {  
  9.             return result.toString();  
  10.         }  
  11.         // 使用整體狀態為空來代表解析結束  
  12.         if (states.isEmpty()) {  
  13.             throw new IllegalStateException("unexpected char '" + currentChar + "' at position " + scanner.getIndex());  
  14.         }  
  15.         // 將字符規整成事件對象,有利于參數的傳遞  
  16.         Event event = Event.parseToEvent(currentChar, scanner.getIndex());  
  17.         if (event == null) {  
  18.             throw new IllegalStateException("unknown char '" + currentChar + "' at position " + scanner.getIndex());  
  19.         }  
  20.         // 這里需要一個 Map 來映射狀態和狀態處理器  
  21.         STATE_TO_HANDLER_MAPPING.get(states.peek()).handle(event, states, result);  
  22.     }  
  23.  

小結

狀態模式

如果你對設計模式較熟的話,會發現這不就是狀態模式嘛。

有解釋說,狀態模式會將事件類型也再解耦,即 StateHandler 里不只有一個方法,而是會有八個方法,分別為 handleStart,HandleListEle 等,但我覺得模式并不是定式,稍微的變形是沒有問題的,如果單個事件類型的處理足夠復雜,將其再拆分更合理一些。

代碼結構

最后,對比 if-else 實現,從代碼量上來看,狀態機實現增加了很多,這是解耦的代價,當然也有很多重復代碼的緣故,比如在容器閉合時校驗當前容器是否內嵌容器,并針對內嵌容器做處理的邏輯就完全一樣,為了代碼清晰我就沒有再抽取方法。

從可維護性上來說,狀態機實現由于邏輯拆分比較清晰,在添加或刪除一種狀態時比較方便,添加一個狀態和狀態處理器就行,但在添加一種事件類型時較為復雜,需要修改所有狀態處理器里的實現,不過從整體上來看是利大于弊的,畢竟代碼清晰易改動最重要。

了解了狀態機實現的固定套路之后,你也可以寫出高大上的狀態機代碼了,快 Get 起來替換掉項目里雜亂的 if-else 吧。 

 

責任編輯:龐桂玉 來源: Hollis
相關推薦

2024-11-04 09:41:47

2020-04-09 08:29:50

編程語言事件驅動

2020-10-22 09:20:22

SQLNoSQL 數據庫

2025-10-27 01:33:00

if-else代碼重構

2025-06-26 01:10:00

服務定位解析器Spring

2021-01-29 07:45:27

if-else代碼數據

2022-07-04 08:32:55

Map函數式接口

2020-07-17 13:01:44

If-Else代碼編程

2025-04-21 00:00:05

2022-07-11 08:16:55

策略模式if-else

2022-06-14 10:49:33

代碼優化Java

2019-03-17 16:48:51

物聯網云計算數據信息

2013-03-06 10:28:57

ifJava

2023-06-02 07:30:24

If-else結構流程控制

2013-11-28 14:34:30

微軟WP

2021-04-13 06:39:13

代碼重構code

2020-12-29 09:16:36

程序員對象開發

2021-11-10 16:03:42

Pyecharts Python可視化

2021-03-10 07:20:43

if-else靜態代碼

2021-11-25 07:43:56

CIOIT董事會
點贊
收藏

51CTO技術棧公眾號

每日在线更新av| 99在线视频播放| www成人啪啪18软件| 成人国产网站| 一区二区三区四区av| 精品999在线观看| 国产乡下妇女三片| 欧美日韩视频一区二区三区| 国产视频一区在线| 欧美精品久久久久久久久25p| 97超碰在线公开在线看免费| 91亚洲国产成人精品一区二三| 国产精品久久久久久av| 黄色一级免费视频| 精品国产aⅴ| 精品福利在线导航| 久久婷五月综合| 17videosex性欧美| 自拍视频在线观看一区二区| 精品无人乱码一区二区三区的优势| 少妇无套内谢久久久久| 欧美日韩在线大尺度| 日韩精品在线观看一区| 欧美性受xxxx黒人xyx性爽| 精品极品在线| 一区二区欧美国产| 一区二区免费电影| 日中文字幕在线| 国产aⅴ综合色| 国产在线播放91| 人人妻人人爽人人澡人人精品 | 日本少妇全体裸体洗澡| 青青草91久久久久久久久| 亚洲级视频在线观看免费1级| 午夜免费福利视频在线观看| 亚洲伊人av| 亚洲一区二区影院| 天天综合中文字幕| 国产视频精品久久| 91在线观看地址| 国产精品一区二区在线观看| 国产女人爽到高潮a毛片| 日韩影院精彩在线| 青青在线视频一区二区三区| 免费在线观看黄网站| 国产一区二区三区四区老人| 久久伊人精品一区二区三区| 午夜黄色福利视频| 欧美亚洲国产激情| 亚洲日本成人女熟在线观看| 亚洲中文字幕无码av| 国产精品17p| 欧美sm极限捆绑bd| 国产69视频在线观看| 精品亚洲二区| 91精品国产高清一区二区三区蜜臀| 亚洲欧美国产日韩综合| 成人全视频免费观看在线看| 在线看不卡av| 992kp快乐看片永久免费网址| 欧美成人ⅴideosxxxxx| 日本丶国产丶欧美色综合| av动漫在线观看| gogo亚洲高清大胆美女人体| 欧美吻胸吃奶大尺度电影 | 亚洲欧美在线第一页| 国产中文字幕一区二区| 一区二区三区韩国免费中文网站| 日韩精品高清在线| 国产成人精品无码免费看夜聊软件| 伊人久久大香线蕉| 欲色天天网综合久久| 国产一二三四区在线| 日韩欧美三级| 欧美成人激情图片网| 久久久99精品| 国产精品久久久免费| 国产成人激情小视频| 中文字幕乱码人妻无码久久| 国产一区二区三区在线观看免费| 欧美久久视频| 在线成人小视频| 免费看的av网站| 国产精品任我爽爆在线播放| aaaa黄色片| 啪啪免费视频一区| 亚洲va韩国va欧美va| 人妻久久久一区二区三区| 一区二区精品伦理...| 欧美在线看片a免费观看| 欧美女同在线观看| 色妞ww精品视频7777| 精品视频在线播放免| 国产精品成人在线视频| 欧美大片一区| 欧美亚洲一级片| 91亚洲精品国偷拍自产在线观看| 懂色av一区二区三区免费观看| 久久亚洲高清| 免费黄色在线| 福利视频第一区| 男人搞女人网站| 亚洲综合色婷婷在线观看| 日韩精品久久久久久福利| 超碰人人人人人人人| 亚洲国产免费看| 国产噜噜噜噜噜久久久久久久久| 亚州男人的天堂| 亚洲欧洲精品天堂一级| 久久综合九色综合88i| 日韩第二十一页| 日韩精品高清在线| 美女福利视频在线观看| 噜噜噜91成人网| 成人在线资源网址| 欧美猛烈性xbxbxbxb| 欧美色欧美亚洲高清在线视频| 欧美一级小视频| 久久综合影院| 97久久国产精品| 99精品久久久久久中文字幕 | 91精品国产自产在线| 少妇人妻精品一区二区三区| 亚洲三级久久久| wwwwww.色| 欧美激情影院| 久久久久久久av| 国产精品无码专区av免费播放| 久久久久久久性| 欧美久久久久久久久久久久久| 国产精品久久免费视频| 综合网日日天干夜夜久久| 69成人免费视频| 国产成都精品91一区二区三| 亚洲一区二区精品在线| 日韩不卡在线| 亚洲色图校园春色| 亚洲第一精品在线观看| 成人av网站免费观看| 红桃一区二区三区| 不卡的国产精品| 日韩一级黄色av| 中文字幕一区二区人妻| 亚洲国产精品ⅴa在线观看| 国产免费成人在线| 亚洲婷婷影院| 人体精品一二三区| 欧美视频免费一区二区三区| 欧美日韩另类在线| 精品黑人一区二区三区观看时间| 亚洲激情综合| 久久精品国产美女| 97成人资源| 亚洲欧美国产日韩天堂区| 欧美一区二区激情视频| 91小视频在线观看| 黄色片一级视频| 国产欧美一区| 国产精品露脸自拍| 欧美性videos| 日韩亚洲欧美中文三级| 精品97人妻无码中文永久在线| 韩国成人在线视频| 丰满人妻一区二区三区53号| 日韩视频一区二区三区四区| 欧美精品videos性欧美| 五月天婷婷视频| 色综合激情久久| 成人在线手机视频| 国产一区二区三区免费| 免费极品av一视觉盛宴| 久久资源综合| 国产精品盗摄久久久| 日本在线免费播放| 日韩亚洲电影在线| 日韩三级视频在线| 国产欧美一区二区在线| 国产女同无遮挡互慰高潮91| 欧美国产高清| 欧美日韩国产精品一卡| 国产精品伦一区二区| 美日韩精品免费视频| 亚洲奶汁xxxx哺乳期| 色一情一乱一乱一91av| 强制高潮抽搐sm调教高h| 国产成人av电影在线| 人妻熟妇乱又伦精品视频| 第一会所sis001亚洲| 古典武侠综合av第一页| 写真福利精品福利在线观看| 久久影视电视剧免费网站清宫辞电视| 欧性猛交ⅹxxx乱大交| 91久久精品国产91性色tv| 99成人在线观看| 91亚洲资源网| 精品国产鲁一鲁一区二区三区| 日韩视频三区| 中文字幕一区二区三区在线乱码| av日韩精品| 国产精品视频导航| av免费不卡| www.亚洲一区| 少妇性bbb搡bbb爽爽爽欧美| 337p亚洲精品色噜噜| 在线观看黄网站| 亚洲女同女同女同女同女同69| 菠萝菠萝蜜网站| 国产精品白丝jk白祙喷水网站| a√天堂在线观看| 亚洲精品888| 色一情一乱一伦一区二区三区丨| 精品精品视频| 国产精品久久久久久久久久久久久| 里番在线播放| 久久综合国产精品台湾中文娱乐网| 青青久草在线| 亚洲精品成人免费| av官网在线观看| 欧美艳星brazzers| 黄色在线观看国产| 亚洲在线观看免费视频| 91久久久久久久久久久久久久| 久久日韩精品一区二区五区| 久久久久久婷婷| 国产精品1024| 黄色小视频免费网站| 老**午夜毛片一区二区三区| 欧美久久久久久久久久久久久| 亚洲女同一区| 一区国产精品| 日韩视频在线观看| 日韩欧美一区二区三区四区| 女人抽搐喷水高潮国产精品| 丁香婷婷久久久综合精品国产| 性欧美video另类hd尤物| 国产精品高潮在线| 日韩中文在线播放| 日韩美女毛茸茸| 亚洲人体视频| 琪琪亚洲精品午夜在线| 春色校园综合激情亚洲| 久久全球大尺度高清视频| 日韩电影免费观看| 九九热在线精品视频| av香蕉成人| 免费97视频在线精品国自产拍| 麻豆91在线| 欧美精品做受xxx性少妇| av色综合久久天堂av色综合在| 欧美超级乱淫片喷水| www.在线视频| 欧美黄色三级网站| 女同视频在线观看| 高清视频欧美一级| bbw在线视频| 欧美亚洲国产成人精品| 另类图片综合电影| 国产精品草莓在线免费观看| 国产69精品久久久久9999人| 国产日本欧美一区二区三区在线| 欧美成人福利| 成人自拍爱视频| 日韩极品在线| 性欧美精品一区二区三区在线播放 | 欧美日韩精品一区二区天天拍小说| 久草热在线观看| 欧美精品久久久久久久久老牛影院| 91麻豆成人精品国产| 欧美一区二区三区视频免费| 亚洲h视频在线观看| 亚洲第一天堂av| 色鬼7777久久| x99av成人免费| 天天色天天射天天综合网| 性色av一区二区三区免费| 在线天堂资源| 国产乱肥老妇国产一区二 | 欧美日韩成人免费观看| 欧美日韩国产丝袜另类| 中文字幕一区2区3区| 日韩国产在线观看| 日韩av在线影院| 亚洲av永久无码国产精品久久| 亚洲国产精品字幕| av大片在线看| 久久久久久久久久久免费精品| 亚洲综合电影| 91免费版网站在线观看| 亚洲妇女av| 成人在线观看www| 国产一级久久| 亚洲综合婷婷久久| kk眼镜猥琐国模调教系列一区二区| 日本成人免费视频| 一区二区三区免费网站| 精品人妻一区二区三区免费看 | 欧美最猛性xxxx| 高清一区二区中文字幕| 蜜桃视频日韩| 欧美激情第二页| 国产超碰在线播放| 不卡影院免费观看| 波多野结衣喷潮| 欧美日韩亚洲一区二区| 国产特黄一级片| 亚洲品质视频自拍网| 日本一级理论片在线大全| 日本欧美精品在线| 大陆精大陆国产国语精品 | 精品999网站| 亚洲成人福利在线观看| 成人在线视频一区| 免费成人美女女在线观看| 欧美日韩在线第一页| www.蜜臀av| 日韩中文字幕视频在线观看| 男人最爱成人网| 国产一区二区三区免费不卡| 亚欧美无遮挡hd高清在线视频| 99蜜桃臀久久久欧美精品网站| 丁香婷婷综合激情五月色| 91杏吧porn蝌蚪| 欧美日韩高清在线播放| 国产福利小视频在线| 欧美亚洲激情在线| swag国产精品一区二区| 最新欧美日韩亚洲| 日本在线不卡视频| 人妻体内射精一区二区| 精品久久久久久中文字幕大豆网 | 成人午夜视频网站| 久久免费在线观看视频| 欧美一区二区视频在线观看2022| 97超碰国产一区二区三区| 国产成人精品一区二区在线 | 400部精品国偷自产在线观看 | 欧美天天综合色影久久精品| 亚洲伦理在线观看| 欧美日本亚洲视频| 日韩一区二区三区在线看| 日日噜噜夜夜狠狠久久丁香五月 | 97视频中文字幕| 欧美aⅴ99久久黑人专区| 青青草原播放器| 亚洲免费观看高清完整版在线观看| 一级全黄裸体免费视频| 久久久成人的性感天堂| 91成人小视频| 免费观看中文字幕| 国产剧情一区二区| 欧美又粗又大又长| 日韩美女视频在线| 丁香花视频在线观看| 久久大片网站| 久久精品人人| 人妻熟人中文字幕一区二区| 欧美午夜寂寞影院| 黄色网在线播放| 成人看片在线| 麻豆9191精品国产| 超碰97av在线| 日韩欧美激情四射| 高清毛片在线观看| 视频一区二区在线| 黄色小说综合网站| 久久99久久久| 日韩精品中文字幕有码专区| av一区在线播放| 国产又粗又爽又黄的视频| 成人动漫一区二区在线| 国产91精品一区| 色吧影院999| 在线日韩成人| 日本在线观看a| 亚洲日本韩国一区| 日本xxxx人| 国产精品视频99| 激情欧美丁香| jizz18女人高潮| 亚洲精品一区二区三区99| 成人爽a毛片免费啪啪| 在线国产伦理一区| 99久久亚洲一区二区三区青草| 91黑人精品一区二区三区| 久久99国产精品自在自在app| 亚洲都市激情| 性生活在线视频| 91久久精品一区二区二区| 亚洲电影视频在线| 日本一区二区三区视频免费看| 国产精品综合一区二区三区| 亚洲综合久久网| 精品自拍视频在线观看| 视频国产一区| 成人在线观看一区二区| 欧美视频在线不卡| av男人的天堂在线观看| 99精品视频网站| 久久久久一区二区三区四区| 国产成人精品一区二三区四区五区 |