架構(gòu)學(xué)習(xí)筆記-如何搭建一個系統(tǒng)?設(shè)計模式?架構(gòu)思想姚糊?通通都有~

如何搭建一個系統(tǒng)?

首先要學(xué)會搭建一個系統(tǒng)贸辈,你需要先成為一個優(yōu)秀的工程師肠槽。一個優(yōu)秀的工程師應(yīng)該【具備扎實(shí)的基礎(chǔ)能力】、【書寫高質(zhì)量代碼】秸仙、【擁有良好的風(fēng)險控制能力】以及【具備一定的測試基礎(chǔ)】。

(1)席吴,系統(tǒng)架構(gòu)

1)捞蛋,評價一個優(yōu)秀的系統(tǒng)的指標(biāo)

  1. 代碼具備一定的可讀性、擴(kuò)展性拟杉。 => 也使得代碼的干凈,不混亂啼染。 => 這里混亂的定義是相對的焕梅,也就是說,如果你自己按照一定的邏輯封裝的贞言,那么對于自己而言是清晰的;但是如果這個代碼給到其他的人看弟蚀,在不清楚你的思路的情況下會存在一些問題(變量名任意起酗失、方法一坨等),所以面對可讀性的挑戰(zhàn)规肴,我們就可以通過良好的結(jié)構(gòu)去管理這些復(fù)雜性夜畴,我們把這個結(jié)構(gòu)稱之為【系統(tǒng)架構(gòu)】贪绘。
  2. 代碼的具備的一定的健壯性央碟。
  3. 在排查問題的時候也容易定位。

2)亿虽,用發(fā)展的眼觀去看待一個功能的設(shè)計

ps:不僅僅用發(fā)展的眼光去看待一個功能的設(shè)計,其實(shí)編碼更像一種“救世主”模式粘秆,你通過代碼實(shí)現(xiàn)的一個個功能,就是你的一個個的作品翻擒,而于這些作品而言牛哺,它的好壞完全取決于你,基于換位思考的原則巩趁。

A01:示例偽代碼

假設(shè)我們有一個http接口,需要返回用戶的信息议慰。用戶信息包括:用戶昵稱奴曙、用戶vip等級、用戶標(biāo)簽洽糟、用戶余額、余額歷史以來用戶最貴一次消費(fèi)拍霜。

public Result<?> getUserInfo(String userId){  
    log.info("打印方法入口日志");
    log.info("校驗(yàn)入?yún)?);
    try{
        log.info("ServiceA -> 獲取用戶基礎(chǔ)信息");
        log.info("ServiceB -> 獲取用戶特殊信息");
        // log.info("ServiceC -> 獲取當(dāng)前用戶充值的總金額");
        log.info("ServiceC -> 獲取當(dāng)前用戶余額");
        log.info("ServiceD -> 獲取用戶的消費(fèi)記錄");
        log.info("利用strem流的方式獲取最近一次最貴的消費(fèi)");
    }catch(Exception ex){
        log.error("捕獲異常日志 -> ", ex);
    }
    log.info("打印訪問成功出口日志");
    return ResultGenerator.genSuccessResult("返回接口處理結(jié)果");
}

分析上述代碼中存在的問題

  1. 業(yè)務(wù)變動 => 如果新增一個接口的話薪介?
    • 通用日志模塊是存在優(yōu)化空間的,比如打印方法入?yún)⒌劳怠⒊鰠ⅰ?=> 通俗的講就是如果新增接口,每個接口都要添加入?yún)⑹愿怼⒊鰠⒌拇蛴 ?/li>
    • 通用異常處理模塊抠蚣。 => 這里如果是針對業(yè)務(wù)本身的而設(shè)計的異常處理,那么無可厚非嘶窄,但是如果從 try ... catch ... 看的話,如果是為了替代全局異常而將所有的方法都添加在函數(shù)體內(nèi)的話就會存在問題了吻谋。
  2. 功能變動 => 如果替換需求中的“計算”部分现横,轉(zhuǎn)為獲取用戶的充值總額,用戶的基礎(chǔ)等不變戒祠。
    • 對應(yīng)的入?yún)?增加用戶姓名查詢)是可能變動的,那么意味著入?yún)⒌拇蛴〉颓А⑿r?yàn)都需要修改馏颂。
    • 其他的用戶信息的獲取也是需要是復(fù)制一份的。
    • 對于返回信息而言也是如此救拉,此時需要修改新的新的信息的話,那就需要往這個代碼里添加新的業(yè)務(wù)邏輯告喊。而這個類一旦有變化壹无,就涉及對這個類的回歸驗(yàn)證
  3. 問題抽象
    • 存在部分冗余代碼地淀,在邏輯變動的時候會發(fā)現(xiàn),代碼的冗余會帶來修改的效率低下帮毁、存在漏改的風(fēng)險、存在邏輯不一致的風(fēng)險烈疚。
A02:通過模版方法解決部分冗余的問題
  1. 算法簡介:統(tǒng)一算法框架,將算法要素暴露給子類去實(shí)現(xiàn)猾浦。
  2. 算法核心
    • 控制業(yè)務(wù)執(zhí)行步驟,例如先打印日志金赦、再校驗(yàn)对嚼,執(zhí)行業(yè)務(wù)邏輯,統(tǒng)一處理異常漠烧。
    • 和業(yè)務(wù)相關(guān)的核心要素實(shí)現(xiàn),在每個業(yè)務(wù)中是不一樣的已脓,所以這些需要子類自己去實(shí)現(xiàn)乏奥。
  3. 偽代碼示例
public abstract class ServiceTemplate<T, R> {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    /**業(yè)務(wù)執(zhí)行步驟*/
    public R process(T request) {
        //1,打印入口日志
        Logger.info("start invoke, request=" + request);
        try {
            //2,校驗(yàn)參數(shù)(抽象方法)
            validParam(request);
            //3,子類實(shí)現(xiàn)邏輯(業(yè)務(wù)的具體實(shí)現(xiàn))
            R response = doProcess(request):
            //4,打印出口日志
            logger.info("end invoke, response=" + response + ", costTime=" + timeCost);return response;
        } catch (Exception e) {
        }
    }
    /**父類抽象方法:參數(shù)校驗(yàn),具體的邏輯由子類自己實(shí)現(xiàn)*/
    protected abstract void validParam(T request);
    
    /**父類抽象方法:執(zhí)行業(yè)務(wù)邏輯恨诱,具體的邏輯由子類自己實(shí)現(xiàn)*/
    protected abstract R doProcess(T request);
}
  1. 子類實(shí)現(xiàn)修改
public Result<?> getUserInfo(String userId){  

    return (new ServiceTemplate<String, Result<?>>){
        @Override
        public void validParam(string request) {
            log.info("校驗(yàn)入?yún)?);
        }
    
        @Override
        public Result<?> doProcess(String request) {
            log.info("ServiceA -> 獲取用戶基礎(chǔ)信息");
            log.info("ServiceB -> 獲取用戶特殊信息");
            // log.info("ServiceC -> 獲取當(dāng)前用戶充值的總金額");
            log.info("ServiceC -> 獲取當(dāng)前用戶余額");
            log.info("ServiceD -> 獲取用戶的消費(fèi)記錄");
            log.info("利用strem流的方式獲取最近一次最貴的消費(fèi)");
            return ResultGenerator.genSuccessResult("返回接口處理結(jié)果");
        }
    }).process(userId); // 調(diào)用業(yè)務(wù)執(zhí)行步驟的相關(guān)方法
}
  1. 優(yōu)化后分析好處與仍然存在的問題
    • 相關(guān)公共的邏輯被抽象了照宝,例如日志打印句葵、異常處理等。
    • 不用擔(dān)心接口有遺漏步驟及搞錯步驟順序乍丈,例如入?yún)⑿r?yàn)在執(zhí)行業(yè)務(wù)流程之前。
    • 子類只需要關(guān)注自己業(yè)務(wù)邏輯的實(shí)現(xiàn)即可忆矛。
    • 如果對于接口要增加一些公用的能力的話请垛,可以直接在方法內(nèi)部抽象接口中添加洽议,
A03:通過流程引擎來優(yōu)化步驟的執(zhí)行順序
  1. 算法簡介:將要執(zhí)行的邏輯看成是一個個步驟的串接漫拭,由統(tǒng)一的角色來管理步驟的執(zhí)行順序,這個角色就是流程引擎审胚。
  2. 算法核心:算法的核心體現(xiàn)就是“管理者”角色的出現(xiàn),當(dāng)然需要將可以獨(dú)立的功能抽象成一個一個的 執(zhí)行器菲盾,這些執(zhí)行器可以是不同的業(yè)務(wù)領(lǐng)域類各淀,而管理者的職責(zé)就是將這些通用的流程放在一個池子中诡挂,根據(jù)不同的耦合業(yè)務(wù)場景從池子中獲取不同的執(zhí)行器,去編排到不同的業(yè)務(wù)流程中璃俗。
    • 【核心優(yōu)勢 -> 避免冗余】:利用抽象和池化思想,將不同的執(zhí)行器統(tǒng)一管理苟穆,從而避免了代碼的冗余唱星。
    • 【核心優(yōu)勢 -> 最小修改】:如果業(yè)務(wù)邏輯在組織過程中,需要增加一個環(huán)節(jié)间聊,可以方便的通過直接添加一個執(zhí)行器即可。
    • 【核心優(yōu)勢 -> 方便追蹤】:在原始的模板方法中可以增加耗時統(tǒng)計處理型豁,此時也可以印證模板方法的優(yōu)勢尚蝌,根據(jù)耗時統(tǒng)計可以知道每個執(zhí)行器的耗時情況,方便追蹤日志飘言,去找到最耗時的執(zhí)行器去進(jìn)行精細(xì)化的定位。
    • 【核心優(yōu)勢 -> 利于分工】:每個處理器在約定職責(zé)的情況下可以獨(dú)立開發(fā)泵喘,當(dāng)然就可以獨(dú)立測試泪电,減少整體出錯導(dǎo)致排查問題混亂的情況出現(xiàn)相速。 => 同時代碼的可讀性也會翻倍增加鲜锚。 => 當(dāng)然模塊化的設(shè)計,也就更加利于各個處理器以循環(huán)和分支的方式進(jìn)行組合芜繁。

![[Pasted image 20231030214347.jpg|給出參考連接作者的一副圖方便理解對應(yīng)的優(yōu)勢]]


Pasted image 20231030214347.jpg
  1. 示例代碼:這里不再對文章中的方法進(jìn)行整理,感興趣的話可以直接查看原文蔬捷。我更傾向于這是一種代碼的組織方式榔袋,你可以通過示例中去通過接口和對應(yīng)的實(shí)現(xiàn)類去創(chuàng)建不同的執(zhí)行器,然后通過模板方法再去組織業(yè)務(wù)凰兑,也就是通過模板方法中抽象接口去組織業(yè)務(wù)流程,充當(dāng)一個管理者的角色吏够。 => 從這個角度看,去實(shí)現(xiàn)自己的流程引擎就需要根據(jù)自己的代碼架構(gòu)去實(shí)現(xiàn)了播急,而實(shí)現(xiàn)方式則不拘泥于這一種。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旅择,一起剝皮案震驚了整個濱河市生真,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柱蟀,老刑警劉巖蚜厉,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異术瓮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)胞四,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氓侧,“玉大人导狡,你說我怎么就攤上這事『蹬酰” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵廊佩,是天一觀的道長。 經(jīng)常有香客問我标锄,道長料皇,這世上最難降的妖魔是什么星压? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任揍诽,我火速辦了婚禮,結(jié)果婚禮上舌劳,老公的妹妹穿的比我還像新娘军洼。我一直安慰自己演怎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布甘桑。 她就那樣靜靜地躺著,像睡著了一般铆帽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锄贼,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天女阀,我揣著相機(jī)與錄音,去河邊找鬼浸策。 笑死,一個胖子當(dāng)著我的面吹牛惫确,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚯舱,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼枉昏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了兄裂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤谈撒,失蹤者是張志新(化名)和其女友劉穎匾南,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛆楞,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年橙数,在試婚紗的時候發(fā)現(xiàn)自己被綠了帅戒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崖技。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡迎献,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吁恍,到底是詐尸還是另有隱情播演,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布翼闽,位于F島的核電站,受9級特大地震影響感局,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜询微,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一狂巢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧隧膘,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽艇肴。三九已至,卻和暖如春再悼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背冲九。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工跟束, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丑孩,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓略贮,卻偏偏與公主長得像仗岖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轧拄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容