自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

成為工程師 - 搭建系統(tǒng)先搭建框架

開發(fā) 架構(gòu)
對于流程引擎,我們只是給出了一種最最基礎(chǔ)的實現(xiàn)方式而已,但是對于很多系統(tǒng)來說,這么設(shè)計已經(jīng)足夠了。事實上,真正強大的流程引擎還包括【分支循環(huán)】【異步化】【可視化界面管理】等各種高階功能,你可以自己做一些了解。

作為工程師,日常的工作基本上都是圍繞著【系統(tǒng)】展開的?!敬罱ㄒ粋€系統(tǒng)】是工程師必須具備的最基礎(chǔ)能力。

從業(yè)至今,我自己負責(zé)過很多系統(tǒng),也看到過很多系統(tǒng)。有的系統(tǒng)搭建得非常優(yōu)雅,無論是可讀性還是擴展性都非常好。說白了就是代碼看起來清晰干凈,研發(fā)起來快捷且安全,排查問題也容易定位。但還有一些系統(tǒng)你就是看上好幾遍代碼都捋不清邏輯,改造的時候更是無從下手。

一個系統(tǒng)存在復(fù)雜的業(yè)務(wù)邏輯是正常的,而一個優(yōu)雅的系統(tǒng)是能夠通過良好的結(jié)構(gòu)去管理這些復(fù)雜性。我把這個結(jié)構(gòu)稱之為【系統(tǒng)框架】。

搭建系統(tǒng)框架是系統(tǒng)建設(shè)的第一步,也是最重要一步。我們這篇文章就來聊聊如何搭建一個好的系統(tǒng)框架。

我們先看一個反例:

反例時間

假設(shè)我們有一個http接口,需要返回用戶的信息。用戶信息包括:用戶昵稱、用戶vip等級、用戶標(biāo)簽、用戶余額、余額歷史以來充值總額、用戶最貴一次消費。

下面的代碼是一種典型的實現(xiàn)方式(可以看注釋來了解步驟):

圖片

很多同學(xué)看到這樣的代碼覺得已經(jīng)挺好了。有日志、有注釋、有異常處理,代碼也沒有擠在一堆。但真的是這樣嗎?

我認為這樣的代碼確實反映了工程師一定的技術(shù)素養(yǎng),但起碼存在以下這些問題:

【Q1】如果新增接口,所有的日志打印要冗余寫一遍,包括入口日志、出口日志、異常日志。

【Q2】如果新增接口,try-catch的異常處理邏輯也需要冗余重寫。

【Q3】如果新增一個只獲取用戶金額信息的接口,需要冗余復(fù)制上述代碼中和金額相關(guān)的部分。

【Q4】如果接口需要修改,返回新的信息,那就需要往這個代碼里添加新的業(yè)務(wù)邏輯。而這個類一旦有變化,就涉及對這個類的回歸驗證。

【Q5】如果我要同時支持可以根據(jù)用戶昵稱來搜索用戶信息,那么我要新增一個基本完全一樣的接口(除了入?yún)⒉煌?/p>

(記住以上這些問題,我們下面會逐一來解決)

所以,如果用發(fā)展的眼光(需求新增)去看這段代碼,你可以基本判斷以后會存在大量的邏輯冗余。

大量的冗余會帶來研發(fā)的低效、升級的遺漏、邏輯不一致的風(fēng)險等等。

此外,不同工程師可能都有自己的編碼習(xí)慣,同樣是處理日志,異常,寫法可以迥然不同。

結(jié)合在大廠多年的經(jīng)驗,優(yōu)雅的系統(tǒng)會結(jié)合兩種設(shè)計方式來解決這類冗余的問題。我們一起來看看。

一、模板模式

【模板模式】就是設(shè)計模式中的“模板方法模式”。模板方法模式的核心思想就是:統(tǒng)一算法框架,暴露算法要素給子類來實現(xiàn)。

看定義還是抽象了一些,我們直接看例子。

下圖就是一個定義了算法框架的抽象模板類:

圖片

可以看到,process方法里僅做了兩件事:

【1】實現(xiàn)了所有接口的共用邏輯。比如打日志、計算耗時、捕獲異常并處理。

【2】確定了步驟(步驟也稱之為算法框架)。比如先校驗參數(shù),后執(zhí)行業(yè)務(wù)邏輯。

基于上面的模板,我們的服務(wù)只需要做如下實現(xiàn)就可以了:

圖片

下面我們根據(jù)【模板模式】的思想修改我們的反面案例,我們的代碼就變成了:

圖片

可以看到,通過模板模式,你起碼會有這樣幾個好處:

【1】每個接口都不用擔(dān)心忘了執(zhí)行必要的公共邏輯,例如打印日志、異常處理。

【2】不用擔(dān)心接口有遺漏步驟及搞錯步驟順序,例如入?yún)⑿r炘趫?zhí)行業(yè)務(wù)流程之前。

【3】接口只需要關(guān)心自己業(yè)務(wù)邏輯的實現(xiàn)即可。

【4】所有接口打印的日志及異常處理方式確保是一致的,方便監(jiān)控和定位問題。

【5】如果需要增加一些公用的能力,例如埋點上報某個統(tǒng)計平臺,只需要在框架中添加邏輯,所有接口都直接生效。

我們使用【模板模式】解決了業(yè)務(wù)無關(guān)邏輯的冗余問題,也就是上述針對反面例子提出的問題中的Q1、Q2,下一步我們要動手解決業(yè)務(wù)邏輯冗余的問題,也就是針對問題Q3、Q4、Q5。

二、流程引擎

流程引擎的核心思想是:將要執(zhí)行的邏輯看成是一個個步驟的串接,由統(tǒng)一的角色來管理步驟的執(zhí)行順序,這個角色就是流程引擎。

我們用兩張圖來對比下使用流程引擎和常規(guī)瀑布式編碼的不同。

1.流程式編碼 vs 瀑布式編碼

圖片

上圖分別展示了兩種編碼法方式【瀑布式編碼】和【流程式代碼】。

【瀑布式編碼】就是從上往下按照步驟把業(yè)務(wù)邏輯寫完。

【流程式編碼】是先把可以獨立的功能抽成一個個執(zhí)行器。不同的服務(wù)根據(jù)自己功能的需求來串接這些執(zhí)行器。

兩者對比,流程式編碼有這樣一些好處:

【避免冗余】:同樣的業(yè)務(wù)邏輯只有一份代碼。

【最小修改】:如果需要加一個環(huán)節(jié),只需要新增一個處理器,并且編排到流程中即可,對已有代碼沒有任何侵入。

【方便追蹤】:我們可以在每一個節(jié)點執(zhí)行完以后,在流程引擎中添加一些日志,以此來追蹤執(zhí)行過程。例如在哪里中斷了?哪個執(zhí)行器耗時最長?

【利于分工】:每個處理器約定好職責(zé)就可以獨立開發(fā),并且可以獨立測試。

【可讀性好】:流程式代碼往往在一處編輯所有的步驟,代碼可讀性佳??吹揭粋€流程由哪些節(jié)點組成,基本上就了解大概的邏輯了。

【靈活多變】:流程式編程還可以支持各個處理器以分支和循環(huán)的方式組合。

下面我們就來實現(xiàn)一個簡單的流程引擎,并用它來繼續(xù)改造上面的反例,以此來說明【流程式編程】的思想和好處。

2.處理器設(shè)計

我們先看下處理器的實現(xiàn),處理器是被我們抽取出來處理一塊業(yè)務(wù)邏輯的單元。如下圖標(biāo)識

圖片

在反例里,我們可以抽取三個處理器?!居脩粜畔⑻幚砥鳌俊窘痤~處理器】【消費記錄處理器】。處理器接口如下:

圖片

細心的同學(xué)可能會問,ProcessRequest和ProcessContext是什么?

【ProcessRequest】:對請求信息的封裝。例如用戶的userId、用戶的客戶端信息(IOS、安卓、以及對應(yīng)版本號)、要求轉(zhuǎn)賬的金額、轉(zhuǎn)賬對象等。每個處理器都能夠獲得這些信息,根據(jù)自己的需要去使用。ProcessRequest中所有的值,原則上不允許被修改,以免原始請求信息被污染。

【ProcessContext】:流程執(zhí)行的上下文,用于存放整個流程執(zhí)行過程中的數(shù)據(jù)。在所有執(zhí)行器處理完以后,結(jié)果組裝器可以從ProcessContext中獲取到各種結(jié)果數(shù)據(jù),構(gòu)造返回結(jié)果。

接著我們基于Processor接口,實現(xiàn)三個具體的處理器:

圖片

圖片

圖片

我們處理器就搞定了,等著流程引擎來喚起他們吧!

3.流程引擎設(shè)計

下面我們來看流程引擎的設(shè)計,如下圖標(biāo)識,可以把這些箭頭的控制理解為流程引擎。流程引擎的核心作用就是控制處理器按照指定順序執(zhí)行:

圖片

下面是流程引擎接口:

圖片

流程引擎只有一個start接口用來啟動流程。

以下是流程引擎抽象類。抽象類除了實現(xiàn)對處理器執(zhí)行的控制外,還可以包括日志打印、異常處理等操作。

那一個流程引擎需要執(zhí)行哪些處理器呢?這由子類決定,子類通過實現(xiàn)getProcessors()抽象方法來指定使用的處理器。你看,這里又有模板模式了是不。

圖片

下面看下我們具體的引擎子類是怎樣的:

圖片

可以看到,引擎子類實現(xiàn)getProcessors()方法即可。此方法就是告訴流程引擎具體要執(zhí)行的執(zhí)行器列表及執(zhí)行順序。

如果你走讀代碼到這里,看到list里放的三個處理器名稱,你基本上就知道“用戶查詢接口”提供了怎樣的功能。這就是良好的可讀性。

試想,如果有一天,一個流程中需要新增一個邏輯,我們可以包裝一個新的處理器,然后添加到上圖中的processorList中即可。

每個接口都可以實現(xiàn)一個如上截圖的引擎子類,用以編排需要執(zhí)行的處理器。

4.主入口的改造

當(dāng)引入流程引擎后,我們的主入口(controller)就可以改造成如下這樣(我們附上和之前兩個版本的對比圖):

圖片

你可以很明顯的看到在改造之后,由于業(yè)務(wù)邏輯被內(nèi)聚到一個個處理器中,入口處的代碼變得簡單清晰。同時你再也不用害怕每次業(yè)務(wù)需求都要改這個類,從而變得的膨脹不堪。

5.流程引擎設(shè)計一覽

我們已經(jīng)看到了整個流程引擎的實現(xiàn)過程。最后我們再用一張類圖來一覽整個設(shè)計,相信會幫助你更好地了解這種設(shè)計方法:

圖片

今日總結(jié)

今天,我們正式進入到【成為工程師】的細節(jié)內(nèi)容。我們提到,一個工程師最基礎(chǔ)的能力就是搭建系統(tǒng)。而一個系統(tǒng)要搭建得好,首先就要有一個好的系統(tǒng)框架。

我們先是通過一個反例來說明了典型的瀑布式編碼存在的問題。繼而講了通過模板模式和流程引擎兩種設(shè)計方式來優(yōu)化瀑布式設(shè)計。以此讓系統(tǒng)的擴展變得”容易、安全且規(guī)范“。

對于流程引擎,我們只是給出了一種最最基礎(chǔ)的實現(xiàn)方式而已,但是對于很多系統(tǒng)來說,這么設(shè)計已經(jīng)足夠了。事實上,真正強大的流程引擎還包括【分支循環(huán)】【異步化】【可視化界面管理】等各種高階功能,你可以自己做一些了解。

不過,流程引擎的選擇需要結(jié)合實際情況,不然也會引入額外的復(fù)雜度。

建議你收藏這篇文章,當(dāng)你碰到系統(tǒng)設(shè)計問題的時候,可以回頭來看看,相信可以幫助到你。

下一章我們會接著講系統(tǒng)設(shè)計方面的問題,來講講一個系統(tǒng)要如何分層。

加油吧,未來的架構(gòu)師們!

本文轉(zhuǎn)載自微信公眾號「 CodingBetterLife」,作者「 趙志強 」,可以通過以下二維碼關(guān)注。

轉(zhuǎn)載本文請聯(lián)系「 CodingBetterLife」公眾號。

責(zé)任編輯:武曉燕 來源: CodingBetterLif
相關(guān)推薦

2009-03-20 09:32:52

系統(tǒng)集成工程師素質(zhì)

2013-06-26 10:34:56

工程師?谷歌

2021-03-24 15:15:34

數(shù)據(jù)工程師開發(fā)工具

2018-08-03 15:47:00

iOS框架開發(fā)

2021-01-18 09:00:00

人工智能機器學(xué)習(xí)工程師

2015-12-09 14:37:30

2016-12-13 10:07:50

JAVA框架搭建

2015-12-09 09:03:22

2015-05-20 10:02:02

程序員全棧工程師

2013-03-04 09:55:39

工程師軟件工程師

2019-06-04 08:09:39

物聯(lián)網(wǎng)工程師物聯(lián)網(wǎng)IOT

2018-03-29 11:23:25

IT人員云計算工程師

2016-01-28 11:18:09

卓越前端工程師

2015-08-17 10:32:06

前端工程師優(yōu)秀

2021-03-23 10:04:55

數(shù)據(jù)工程師工具數(shù)據(jù)分析

2015-08-24 09:02:49

前端工程師

2020-10-15 14:23:27

全棧工程師技術(shù)

2021-03-09 10:47:56

系統(tǒng)架構(gòu)師算法工程師人工智能工程師

2020-12-17 12:43:43

前端gup4.0webpack

2022-07-22 09:55:29

軟件工程師
點贊
收藏

51CTO技術(shù)棧公眾號