最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java依賴混亂存在的問(wèn)題與解決方案

 更新時(shí)間:2023年09月21日 14:49:29   作者:GuangHui  
這篇文章主要為大家介紹了java依賴混亂存在的問(wèn)題與解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

呈現(xiàn)的形態(tài)

  • 1.缺少防腐層,業(yè)務(wù)與外部接口耦合;
  • 2.業(yè)務(wù)代碼中出現(xiàn)具體實(shí)現(xiàn)類。

存在的問(wèn)題與解決方案

缺少防腐層,會(huì)讓請(qǐng)求對(duì)象傳導(dǎo)到業(yè)務(wù)代碼中,造成了業(yè)務(wù)與外部接口的耦合,也就是業(yè)務(wù)依賴了一個(gè)外部通信協(xié)議。一般來(lái)說(shuō),業(yè)務(wù)的穩(wěn)定性要比外部接口高,這種反向的依賴就會(huì)讓業(yè)務(wù)一直無(wú)法穩(wěn)定下來(lái),繼而在日后帶來(lái)更多的問(wèn)題。解決方案自然就是引入一個(gè)防腐層,將業(yè)務(wù)和接口隔離開(kāi)來(lái)。

業(yè)務(wù)代碼中出現(xiàn)具體的實(shí)現(xiàn)類,實(shí)際上是違反了依賴倒置原則。因?yàn)檫`反了依賴倒置原則,業(yè)務(wù)代碼也就不可避免地受到具體實(shí)現(xiàn)的影響,也就造成了業(yè)務(wù)代碼的不穩(wěn)定。識(shí)別一段代碼是否屬于業(yè)務(wù),我們不妨問(wèn)一下,看把它換成其它的東西,是否影響業(yè)務(wù)。解決這種壞味道就是引入一個(gè)模型,將業(yè)務(wù)與具體的實(shí)現(xiàn)隔離開(kāi)來(lái)。

編程規(guī)則

依賴倒置原則,即高層模塊不應(yīng)依賴于底層模塊,二者應(yīng)依賴于抽象。抽象不應(yīng)該依賴細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象。

記住一句話

代碼應(yīng)該向著穩(wěn)定性的方向依賴。

缺少防腐層

@PostMapping("/books")
public NewBookResponse createBook(final NewBookRequest request) {
    boolean result = this.service.createBook(request);
    ...
}

按照通常的架構(gòu)設(shè)計(jì)原則,service 層屬于我們的核心業(yè)務(wù),而 controller層屬于接口。二者相較而言,核心業(yè)務(wù)的重要程度更高一些,所以,它的穩(wěn)定程度也應(yīng)該更高一些。同樣的業(yè)務(wù),我們可以用 REST 的方式對(duì)外提供,也可以用 RPC 的方式對(duì)外提供。

NewBookRequest穿越了兩層,職責(zé)不清晰的同時(shí),也存在破壞核心業(yè)務(wù)層穩(wěn)定性的風(fēng)險(xiǎn)。為此,我們只要再引入一個(gè)模型就可以破解這個(gè)問(wèn)題。

class NewBookParameter {
    ...
}
class NewBookRequest {
    public NewBookParameters toNewBookRequest() {
        ...
    }
}
@PostMapping("/books")
public NewBookResponse createBook(final NewBookRequest request) {
    boolean result = this.service.createBook(request.toNewBookParameter());
    ...
}

通過(guò)增加一個(gè)模型,我們就破解了依賴關(guān)系上的糾結(jié)。也許你會(huì)說(shuō),雖然它們成了兩個(gè)類,但是,它們兩個(gè)應(yīng)該長(zhǎng)得一模一樣吧。這算不算是一種重復(fù)呢?但我的問(wèn)題是,它們兩個(gè)為什么要一樣呢?有了兩層不同的參數(shù),我們就可以給不同層次上的模型以不同的約定了。

比如,對(duì)于 controller 層的請(qǐng)求對(duì)象,因?yàn)樗闹饕饔檬莻鬏?,所以,一般?lái)說(shuō),我們約定請(qǐng)求對(duì)象的字段主要是基本類型。而 service 的參數(shù)對(duì)象,因?yàn)樗呀?jīng)是核心業(yè)務(wù)的一部分,就需要全部轉(zhuǎn)化為業(yè)務(wù)對(duì)象。舉個(gè)例子,比如,同樣表示價(jià)格,在請(qǐng)求對(duì)象中,我們可以是一個(gè) double 類型,而在業(yè)務(wù)參數(shù)對(duì)象中,它應(yīng)該是 Price 類型。

業(yè)務(wù)代碼里的具體實(shí)現(xiàn)

@Task
public void sendBook() {
    try {
        this.service.sendBook();
    } catch (Throwable t) {
        this.feishuSender.send(new SendFailure(t)));
        throw t;
    }
}

上面的不符合設(shè)計(jì)原則,它違反了依賴倒置原則。高層模塊不應(yīng)依賴于低層模塊,二者應(yīng)依賴于抽象。抽象不應(yīng)依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)依賴于抽象。

上面這段代碼,在一段業(yè)務(wù)處理中出現(xiàn)了一個(gè)具體的實(shí)現(xiàn),也就是這里的 feishuSender。你需要知道,業(yè)務(wù)代碼中任何與業(yè)務(wù)無(wú)關(guān)的東西都是潛在的壞味道。

在這里,飛書(shū)肯定不是業(yè)務(wù)的一部分,它只是當(dāng)前選擇的一個(gè)具體實(shí)現(xiàn)。換言之,是否選擇飛書(shū),與團(tuán)隊(duì)當(dāng)前的狀態(tài)是相關(guān)的,如果哪一天團(tuán)隊(duì)切換即時(shí)通信軟件,這個(gè)實(shí)現(xiàn)就需要換掉。

識(shí)別一個(gè)東西是業(yè)務(wù)的一部分,還是一個(gè)可以替換的實(shí)現(xiàn),我們不妨問(wèn)問(wèn)自己,如果不用它,是否還有其它的選擇?就像這里,飛書(shū)是可以被其它即時(shí)通信軟件替換的。

另外,常見(jiàn)的中間件,比如,Kafka、Redis、MongoDB 等等,通常也都是一個(gè)具體的實(shí)現(xiàn),其它中間件都可以把它替換掉。所以,它們?cè)跇I(yè)務(wù)代碼里出現(xiàn),那一定就是一個(gè)壞味道了。

既然我們已經(jīng)知道了,這些具體的東西是一種壞味道,那該怎么解決呢?你可以引入一個(gè)模型,也就是這個(gè)具體實(shí)現(xiàn)所要扮演的角色,通過(guò)它,將業(yè)務(wù)和具體的實(shí)現(xiàn)隔離開(kāi)來(lái)。

interface FailureSender {
void send(SendFailure failure);
}
class FeishuFailureSenderS implements FailureSender {
...
}

這里我們通過(guò)引入一個(gè) FailureSender,業(yè)務(wù)層只依賴于這個(gè) FailureSender 的接口就好,而具體的飛書(shū)實(shí)現(xiàn)可以通過(guò)依賴注入的方式注入進(jìn)去。

依賴關(guān)系是軟件開(kāi)發(fā)中非常重要的一個(gè)東西,然而,很多程序員在寫(xiě)代碼的時(shí)候,由于開(kāi)發(fā)習(xí)慣的原因,常常會(huì)忽略掉依賴關(guān)系這件事本身。

現(xiàn)在已經(jīng)有一些工具,可以保證我們?cè)趯?xiě)代碼的時(shí)候,不會(huì)出現(xiàn)嚴(yán)重破壞依賴關(guān)系的情況,比如,像前面那種 service 層調(diào)用 resource 層的代碼。

在 Java 世界里,我們就可以用 ArchUnit 來(lái)保證這一切??疵志筒浑y發(fā)現(xiàn),它是把這種架構(gòu)層面的檢查做成了單元測(cè)試,下面就是這樣的一個(gè)單元測(cè)試:

@Test
public void should_follow_arch_rule() {
    JavaClasses clazz = new ClassFileImporter().importPackages("...");
    ArchRule rule = layeredArchitecture()
    .layer("Resource").definedBy("..resource..")
    .layer("Service").definedBy("..service..")
    .whereLayer("Resource").mayNotBeAccessedByAnyLayer()
    .whereLayer("Service").mayOnlyBeAccessedByLayers("Resource");
    rule.check(clazz);
}

在這里,我們定義了兩個(gè)層,分別是 Resource 層和 Service 層,而且我們要求 Resource 層的代碼不能被其它層訪問(wèn),而 Service 層的代碼只能由 Resource 層方法訪問(wèn)。這就是我們的架構(gòu)規(guī)則,一旦代碼里有違反這個(gè)架構(gòu)規(guī)則的代碼,這個(gè)測(cè)試就會(huì)失敗,問(wèn)題也就會(huì)暴露出來(lái)。

以上就是java依賴混亂存在的問(wèn)題與解決方案的詳細(xì)內(nèi)容,更多關(guān)于java依賴混亂的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于SpringBoot和Vue3的博客平臺(tái)的用戶注冊(cè)與登錄功能實(shí)現(xiàn)

    基于SpringBoot和Vue3的博客平臺(tái)的用戶注冊(cè)與登錄功能實(shí)現(xiàn)

    本教程將指導(dǎo)您如何使用Spring?Boot和Vue3實(shí)現(xiàn)用戶注冊(cè)與登錄功能。我們將使用Spring?Boot作為后端框架,Vue3作為前端框架,同時(shí)使用MySQL作為數(shù)據(jù)庫(kù),感興趣的朋友可以參考一下
    2023-04-04
  • 遞歸之斐波那契數(shù)列java的3種方法

    遞歸之斐波那契數(shù)列java的3種方法

    這篇文章主要為大家詳細(xì)介紹了遞歸之斐波那契數(shù)列java的3種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Java 阻塞隊(duì)列和線程池原理分析

    Java 阻塞隊(duì)列和線程池原理分析

    這篇文章主要介紹了Java 阻塞隊(duì)列和線程池原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • JAVA使用hutool工具實(shí)現(xiàn)查詢樹(shù)結(jié)構(gòu)數(shù)據(jù)(省市區(qū))

    JAVA使用hutool工具實(shí)現(xiàn)查詢樹(shù)結(jié)構(gòu)數(shù)據(jù)(省市區(qū))

    今天通過(guò)本文給大家分享JAVA使用hutool工具實(shí)現(xiàn)查詢樹(shù)結(jié)構(gòu)數(shù)據(jù)(省市區(qū)),代碼分為表結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu),代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-08-08
  • java解析Excel文件的方法實(shí)例詳解

    java解析Excel文件的方法實(shí)例詳解

    在日常工作中,我們常常會(huì)進(jìn)行文件讀寫(xiě)操作,除去我們最常用的純文本文件讀寫(xiě),更多時(shí)候我們需要對(duì)Excel中的數(shù)據(jù)進(jìn)行讀取操作,下面這篇文章主要給大家介紹了關(guān)于java解析Excel文件的方法,需要的朋友可以參考下
    2022-06-06
  • Java的內(nèi)存分配與回收策略詳解

    Java的內(nèi)存分配與回收策略詳解

    這篇文章主要介紹了Java的內(nèi)存分配與回收策略詳解,對(duì)象的內(nèi)存分配,就是在堆上分配,對(duì)象主要分配在新生代的 Eden 區(qū)上,少數(shù)情況下可能直接分配在老年代,分配規(guī)則不固定,取決于當(dāng)前使用的垃圾收集器組合以及相關(guān)的參數(shù)配置,需要的朋友可以參考下
    2023-08-08
  • 使用idea的database模塊繪制數(shù)據(jù)庫(kù)er圖的方法

    使用idea的database模塊繪制數(shù)據(jù)庫(kù)er圖的方法

    這篇文章主要介紹了使用idea的database模塊繪制數(shù)據(jù)庫(kù)er圖,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • 詳解Java編程中面向字符的輸出流

    詳解Java編程中面向字符的輸出流

    這篇文章主要介紹了Java編程中面向字符的輸出流,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • 解決異常:Invalid?keystore?format,springboot配置ssl證書(shū)格式不合法問(wèn)題

    解決異常:Invalid?keystore?format,springboot配置ssl證書(shū)格式不合法問(wèn)題

    這篇文章主要介紹了解決異常:Invalid?keystore?format,springboot配置ssl證書(shū)格式不合法問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • SpringBoot文件上傳與下載功能實(shí)現(xiàn)詳解

    SpringBoot文件上傳與下載功能實(shí)現(xiàn)詳解

    文件上傳與下載是Web應(yīng)用開(kāi)發(fā)中常用的功能之一。接下來(lái)我們將討論如何在Spring?Boot的Web應(yīng)用開(kāi)發(fā)中,如何實(shí)現(xiàn)文件的上傳與下載,感興趣的可以了解一下
    2022-10-10

最新評(píng)論

健康| 宽城| 土默特左旗| 铁岭市| 海南省| 巩留县| 康定县| 平安县| 庄河市| 徐水县| 恭城| 迭部县| 伊金霍洛旗| 辰溪县| 南丹县| 宾川县| 阿克苏市| 图片| 南宁市| 枝江市| 咸宁市| 日土县| 离岛区| 胶南市| 封开县| 邵阳市| 松原市| 库伦旗| 浪卡子县| 曲水县| 盈江县| 阳江市| 新昌县| 高邑县| 琼海市| 乌拉特中旗| 井陉县| 永善县| 中牟县| 闸北区| 广灵县|