欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java依賴混亂存在的問題與解決方案

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

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

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

存在的問題與解決方案

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

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

編程規(guī)則

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

記住一句話

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

缺少防腐層

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

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

NewBookRequest穿越了兩層,職責不清晰的同時,也存在破壞核心業(yè)務層穩(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ān)系上的糾結(jié)。也許你會說,雖然它們成了兩個類,但是,它們兩個應該長得一模一樣吧。這算不算是一種重復呢?但我的問題是,它們兩個為什么要一樣呢?有了兩層不同的參數(shù),我們就可以給不同層次上的模型以不同的約定了。

比如,對于 controller 層的請求對象,因為它的主要作用是傳輸,所以,一般來說,我們約定請求對象的字段主要是基本類型。而 service 的參數(shù)對象,因為它已經(jīng)是核心業(yè)務的一部分,就需要全部轉(zhuǎn)化為業(yè)務對象。舉個例子,比如,同樣表示價格,在請求對象中,我們可以是一個 double 類型,而在業(yè)務參數(shù)對象中,它應該是 Price 類型。

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

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

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

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

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

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

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

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

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

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

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

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

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

@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);
}

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

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

相關(guān)文章

  • Java超詳細分析垃圾回收機制

    Java超詳細分析垃圾回收機制

    一個運行中的程序,?產(chǎn)生的對象是大量的,?如果對象不被繼續(xù)使用,?就會成為垃圾,?最后越堆越多,?最后占滿內(nèi)存,?所以我們要對這些垃圾進行回收,保持程序的正常運行
    2022-05-05
  • Spring相關(guān)知識點的總結(jié)與梳理

    Spring相關(guān)知識點的總結(jié)與梳理

    今天小編就為大家分享一篇關(guān)于Spring相關(guān)知識點的總結(jié)與梳理,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • spring schedule實現(xiàn)動態(tài)配置執(zhí)行時間

    spring schedule實現(xiàn)動態(tài)配置執(zhí)行時間

    這篇文章主要介紹了spring schedule實現(xiàn)動態(tài)配置執(zhí)行時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java?ArrayList遍歷foreach與iterator時remove的區(qū)別

    Java?ArrayList遍歷foreach與iterator時remove的區(qū)別

    這篇文章主要介紹了Java?ArrayList遍歷foreach與iterator時remove的區(qū)別,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • 教你快速搭建sona服務及idea使用sona的方法

    教你快速搭建sona服務及idea使用sona的方法

    Sonar 是一個用于代碼質(zhì)量管理的開放平臺。通過插件機制,Sonar 可以集成不同的測試工具,代碼分析工具,以及持續(xù)集成工具,本文給大家分享搭建sona服務及idea使用sona的方法,感興趣的朋友一起看看吧
    2021-06-06
  • Java8中forEach語句循環(huán)一個List和Map

    Java8中forEach語句循環(huán)一個List和Map

    這篇文章主要給大家介紹了關(guān)于Java8中forEach語句循環(huán)一個List和Map的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • JavaMail入門教程之發(fā)送郵件(3)

    JavaMail入門教程之發(fā)送郵件(3)

    這篇文章主要為大家詳細介紹了JavaMail入門教程之發(fā)送郵件的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • SpringBoot使用TraceId進行日志鏈路追蹤的實現(xiàn)步驟

    SpringBoot使用TraceId進行日志鏈路追蹤的實現(xiàn)步驟

    有時候一個業(yè)務調(diào)用鏈場景,很長,調(diào)了各種各樣的方法,看日志的時候,各個接口的日志穿插,確實讓人頭大,所以為了解決這個問題,本文給大家介紹了SpringBoot使用TraceId進行日志鏈路追蹤的實現(xiàn)步驟,需要的朋友可以參考下
    2024-11-11
  • 教你怎么使用Optional處理null

    教你怎么使用Optional處理null

    今天教各位小伙伴怎么使用Optional處理null,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有很大的幫助,需要的朋友可以參考下
    2021-05-05
  • Java中包的概念和用法實戰(zhàn)案例分析

    Java中包的概念和用法實戰(zhàn)案例分析

    這篇文章主要介紹了Java中包的概念和用法,結(jié)合具體案例形式分析了java包的概念、原理、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下
    2019-09-09

最新評論