国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 Java java教程 JOOQ 不是 Hibernate 的替代品。他們解決不同的問題

JOOQ 不是 Hibernate 的替代品。他們解決不同的問題

Jan 11, 2025 pm 08:10 PM

我最初是用俄語寫這篇文章的。因此,如果您的母語是英語,您可以通過此鏈接閱讀。

在過去一年左右的時間里,我看到一些文章和演講表明 JOOQ 是 Hibernate 的現(xiàn)代且優(yōu)越的替代品。參數(shù)通常包括:

  1. JOOQ 允許您在編譯時驗證所有內(nèi)容,而 Hibernate 則不能!
  2. Hibernate 生成奇怪且并不總是最佳的查詢,而使用 JOOQ,一切都是透明的!
  3. Hibernate 實體是可變的,這很糟糕。 JOOQ 允許所有實體都是不可變的(你好,函數(shù)式編程)!
  4. JOOQ 不涉及任何帶有注釋的“魔法”!

首先聲明,我認為 JOOQ 是一個優(yōu)秀的庫(具體來說是一個庫,而不是像 Hibernate 這樣的框架)。它擅長完成自己的任務(wù)——以靜態(tài)類型的方式使用 SQL,在編譯時捕獲大多數(shù)錯誤。

但是,當我聽到 Hibernate 的時代已經(jīng)過去,我們現(xiàn)在應(yīng)該使用 JOOQ 編寫所有內(nèi)容時,在我看來,這聽起來像是在說關(guān)系數(shù)據(jù)庫的時代已經(jīng)結(jié)束,我們現(xiàn)在應(yīng)該只使用 NoSQL。聽起來很有趣嗎?然而,不久前,這樣的討論還相當嚴肅。

我認為問題在于對這兩個工具解決的核心問題的誤解。在這篇文章中,我的目的是澄清這些問題。我們將探索:

  1. 什么是交易腳本?
  2. 什么是領(lǐng)域模型模式?
  3. Hibernate 和 JOOQ 解決哪些具體問題?
  4. 為什么其中一個不能替代另一個,它們?nèi)绾喂泊妫?/li>

JOOQ Is Not a Replacement for Hibernate. They Solve Different Problems

交易腳本

使用數(shù)據(jù)庫最簡單、最直觀的方法是事務(wù)腳本模式。簡而言之,您將所有業(yè)務(wù)邏輯組織為組合成單個事務(wù)的一組 SQL 命令。通常,類中的每個方法代表一個業(yè)務(wù)操作,并且僅限于一個事務(wù)。

假設(shè)我們正在開發(fā)一個應(yīng)用程序,允許演講者向會議提交演講(為簡單起見,我們只記錄演講的標題)。按照事務(wù)腳本模式,提交演講的方法可能如下所示(使用 JDBI for SQL):

@Service
@RequiredArgsConstructor
public class TalkService {
    private final Jdbi jdbi;

    public TalkSubmittedResult submitTalk(Long speakerId, String title) {
        var talkId = jdbi.inTransaction(handle -> {
            // Count the number of accepted talks by the speaker
            var acceptedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'ACCEPTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // Check if the speaker is experienced
            var experienced = acceptedTalksCount >= 10;
            // Determine the maximum allowable number of submitted talks
            var maxSubmittedTalksCount = experienced ? 5 : 3;
            var submittedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'SUBMITTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // If the maximum number of submitted talks is exceeded, throw an exception
            if (submittedTalksCount >= maxSubmittedTalksCount) {
                throw new CannotSubmitTalkException("Submitted talks count is maximum: " + maxSubmittedTalksCount);
            }
            return handle.createUpdate(
                    "INSERT INTO talk (speaker_id, status, title) " +
                    "VALUES (:id, 'SUBMITTED', :title)"
                ).bind("id", speakerId)
                   .bind("title", title)
                   .executeAndReturnGeneratedKeys("id")
                   .mapTo(Long.class)
                   .one();
        });
        return new TalkSubmittedResult(talkId);
    }
}

在此代碼中:

  1. 我們計算演講者已提交的演講數(shù)量。
  2. 我們檢查是否超出了提交演講的最大允許數(shù)量。
  3. 如果一切正常,我們將創(chuàng)建一個狀態(tài)為“已提交”的新對話。

這里存在潛在的競爭條件,但為了簡單起見,我們不會關(guān)注它。

這種方法的優(yōu)點:

  1. 正在執(zhí)行的 SQL 是簡單且可預(yù)測的。如果需要,可以輕松調(diào)整它以提高性能。
  2. 我們只從數(shù)據(jù)庫中獲取必要的數(shù)據(jù)。
  3. 使用 JOOQ,這段代碼可以寫得更簡單、簡潔,并且可以使用靜態(tài)類型!

缺點:

  1. 僅通過單元測試來測試業(yè)務(wù)邏輯是不可能的。您將需要集成測試(而且是相當多的測試)。
  2. 如果領(lǐng)域很復(fù)雜,這種方法很快就會導(dǎo)致意大利面條式代碼。
  3. 存在代碼重復(fù)的風(fēng)險,隨著系統(tǒng)的發(fā)展,這可能會導(dǎo)致意外的錯誤。

如果您的服務(wù)具有非常簡單的邏輯并且預(yù)計不會隨著時間的推移變得更加復(fù)雜,那么這種方法是有效的并且有意義的。然而,域通常更大。因此,我們需要一個替代方案。

領(lǐng)域模型

領(lǐng)域模型模式的想法是我們不再將業(yè)務(wù)邏輯直接與 SQL 命令綁定。相反,我們創(chuàng)建域?qū)ο螅ㄔ?Java 上下文中為類)來描述行為并存儲有關(guān)域?qū)嶓w的數(shù)據(jù)。

在本文中,我們不會討論貧血模型和豐富模型之間的區(qū)別。如果您有興趣,我已經(jīng)寫了一篇關(guān)于該主題的詳細文章。

業(yè)務(wù)場景(服務(wù))應(yīng)該僅使用這些對象,并避免與特定的數(shù)據(jù)庫查詢綁定。

當然,在現(xiàn)實中,我們可能會混合使用與域?qū)ο蟮慕换ズ椭苯訑?shù)據(jù)庫查詢來滿足性能要求。在這里,我們討論實現(xiàn)領(lǐng)域模型的經(jīng)典方法,其中不違反封裝和隔離。

例如,如果我們正在討論實體“Speaker”和“Talk”,如前所述,域?qū)ο罂赡苋缦滤荆?br>

@Service
@RequiredArgsConstructor
public class TalkService {
    private final Jdbi jdbi;

    public TalkSubmittedResult submitTalk(Long speakerId, String title) {
        var talkId = jdbi.inTransaction(handle -> {
            // Count the number of accepted talks by the speaker
            var acceptedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'ACCEPTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // Check if the speaker is experienced
            var experienced = acceptedTalksCount >= 10;
            // Determine the maximum allowable number of submitted talks
            var maxSubmittedTalksCount = experienced ? 5 : 3;
            var submittedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'SUBMITTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // If the maximum number of submitted talks is exceeded, throw an exception
            if (submittedTalksCount >= maxSubmittedTalksCount) {
                throw new CannotSubmitTalkException("Submitted talks count is maximum: " + maxSubmittedTalksCount);
            }
            return handle.createUpdate(
                    "INSERT INTO talk (speaker_id, status, title) " +
                    "VALUES (:id, 'SUBMITTED', :title)"
                ).bind("id", speakerId)
                   .bind("title", title)
                   .executeAndReturnGeneratedKeys("id")
                   .mapTo(Long.class)
                   .one();
        });
        return new TalkSubmittedResult(talkId);
    }
}

這里,Speaker 類包含提交演講的業(yè)務(wù)邏輯。數(shù)據(jù)庫交互被抽象出來,讓領(lǐng)域模型專注于業(yè)務(wù)規(guī)則。

假設(shè)這個存儲庫接口:

@AllArgsConstructor
public class Speaker {
    private Long id;
    private String firstName;
    private String lastName;
    private List<Talk> talks;

    public Talk submitTalk(String title) {
        boolean experienced = countTalksByStatus(Status.ACCEPTED) >= 10;
        int maxSubmittedTalksCount = experienced ? 3 : 5;
        if (countTalksByStatus(Status.SUBMITTED) >= maxSubmittedTalksCount) {
            throw new CannotSubmitTalkException(
              "Submitted talks count is maximum: " + maxSubmittedTalksCount);
        }
        Talk talk = Talk.newTalk(this, Status.SUBMITTED, title);
        talks.add(talk);
        return talk;
    }

    private long countTalksByStatus(Talk.Status status) {
        return talks.stream().filter(t -> t.getStatus().equals(status)).count();
    }
}

@AllArgsConstructor
public class Talk {
    private Long id;
    private Speaker speaker;
    private Status status;
    private String title;
    private int talkNumber;

    void setStatus(Function<Status, Status> fnStatus) {
        this.status = fnStatus.apply(this.status);
    }

    public enum Status {
        SUBMITTED, ACCEPTED, REJECTED
    }
}

那么SpeakerService可以這樣實現(xiàn):

public interface SpeakerRepository {
    Speaker findById(Long id);
    void save(Speaker speaker);
}

領(lǐng)域模型的優(yōu)點:

  1. 域?qū)ο笈c實現(xiàn)細節(jié)(即數(shù)據(jù)庫)完全解耦。這使得它們可以輕松地通過常規(guī)單元測試進行測試。
  2. 業(yè)務(wù)邏輯集中在域?qū)ο髢?nèi)。與事務(wù)腳本方法不同,這大大降低了邏輯在應(yīng)用程序中傳播的風(fēng)險。
  3. 如果需要,域?qū)ο罂梢酝耆豢勺?,這可以提高使用它們時的安全性(您可以將它們傳遞給任何方法,而不必擔(dān)心意外修改)。
  4. 領(lǐng)域?qū)ο笾械淖侄慰梢蕴鎿Q為值對象,這不僅提高了可讀性,而且保證了賦值時字段的有效性(不能創(chuàng)建內(nèi)容無效的值對象)。

總之,優(yōu)點很多。然而,有一個重要的挑戰(zhàn)。有趣的是,在經(jīng)常宣揚領(lǐng)域模型模式的領(lǐng)域驅(qū)動設(shè)計書籍中,這個問題要么根本沒有提到,要么只是簡單提及。

問題是如何將域?qū)ο蟊4娴綌?shù)據(jù)庫,然后讀取它們?換句話說,如何實現(xiàn)存儲庫?

現(xiàn)在,答案是顯而易見的。只需使用 Hibernate(或者更好的是 Spring Data JPA)即可省去麻煩。但讓我們想象一下,我們正處于一個 ORM 框架尚未發(fā)明的世界。我們該如何解決這個問題呢?

手動測繪

為了實現(xiàn)SpeakerRepository,我還使用JDBI:

@Service
@RequiredArgsConstructor
public class TalkService {
    private final Jdbi jdbi;

    public TalkSubmittedResult submitTalk(Long speakerId, String title) {
        var talkId = jdbi.inTransaction(handle -> {
            // Count the number of accepted talks by the speaker
            var acceptedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'ACCEPTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // Check if the speaker is experienced
            var experienced = acceptedTalksCount >= 10;
            // Determine the maximum allowable number of submitted talks
            var maxSubmittedTalksCount = experienced ? 5 : 3;
            var submittedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'SUBMITTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // If the maximum number of submitted talks is exceeded, throw an exception
            if (submittedTalksCount >= maxSubmittedTalksCount) {
                throw new CannotSubmitTalkException("Submitted talks count is maximum: " + maxSubmittedTalksCount);
            }
            return handle.createUpdate(
                    "INSERT INTO talk (speaker_id, status, title) " +
                    "VALUES (:id, 'SUBMITTED', :title)"
                ).bind("id", speakerId)
                   .bind("title", title)
                   .executeAndReturnGeneratedKeys("id")
                   .mapTo(Long.class)
                   .one();
        });
        return new TalkSubmittedResult(talkId);
    }
}

方法很簡單。對于每個存儲庫,我們編寫一個單獨的實現(xiàn),該實現(xiàn)可以使用任何 SQL 庫(如 JOOQ 或 JDBI)與數(shù)據(jù)庫配合使用。

乍一看(甚至可能是第二眼),這個解決方案可能看起來相當不錯。考慮一下:

  1. 代碼保持高度透明,就像事務(wù)腳本方法一樣。
  2. 僅通過集成測試來測試業(yè)務(wù)邏輯不再有問題。這些僅用于存儲庫實現(xiàn)(可能還有一些 E2E 場景)。
  3. 映射代碼就在我們面前。不涉及 Hibernate 魔法。發(fā)現(xiàn)錯誤?找到正確的線并修復(fù)它。

休眠的必要性

現(xiàn)實世界中的事情會變得更加有趣,你可能會遇到這樣的場景:

  1. 域?qū)ο罂赡苄枰С掷^承。
  2. 一組字段可以組合成一個單獨的值對象(嵌入在 JPA/Hibernate 中)。
  3. 某些字段不應(yīng)在每次獲取域?qū)ο髸r加載,而應(yīng)僅在訪問時加載,以提高性能(延遲加載)。
  4. 對象之間可能存在復(fù)雜的關(guān)系(一對多、多對多等)。
  5. 您只需要在 UPDATE 語句中包含已更改的字段,因為其他字段很少更改,并且通過網(wǎng)絡(luò)發(fā)送它們是沒有意義的(DynamicUpdate 注釋)。

最重要的是,隨著業(yè)務(wù)邏輯和域?qū)ο蟮陌l(fā)展,您需要維護映射代碼。

如果您嘗試自己處理這些要點,您最終會發(fā)現(xiàn)自己(驚訝?。┱诰帉戭愃?Hibernate 的框架 - 或者更可能是一個更簡單的版本。

JOOQ 和 Hibernate 的目標

JOOQ 解決了編寫 SQL 查詢時缺乏靜態(tài)類型的問題。這有助于減少編譯階段的錯誤數(shù)量。通過直接從數(shù)據(jù)庫模式生成代碼,對模式的任何更新都將立即顯示代碼需要修復(fù)的位置(它根本無法編譯)。

Hibernate 解決了域?qū)ο笥成涞疥P(guān)系數(shù)據(jù)庫的問題,反之亦然(從數(shù)據(jù)庫讀取數(shù)據(jù)并將其映射到域?qū)ο螅?/p>

因此,爭論 Hibernate 更差或 JOOQ 更好是沒有意義的。這些工具是為不同的目的而設(shè)計的。如果您的應(yīng)用程序是圍繞事務(wù)腳本范例構(gòu)建的,那么 JOOQ 無疑是理想的選擇。但是,如果您想使用域模型模式并避免使用 Hibernate,則必須在自定義存儲庫實現(xiàn)中享受手動映射的樂趣。當然,如果您的雇主付錢讓您構(gòu)建另一個 Hibernate 殺手,那就沒有問題了。但最有可能的是,他們希望您專注于業(yè)務(wù)邏輯,而不是對象到數(shù)據(jù)庫映射的基礎(chǔ)設(shè)施代碼。

順便說一句,我相信 Hibernate 和 JOOQ 的組合對于 CQRS 效果很好。您有一個執(zhí)行命令的應(yīng)用程序(或其邏輯部分),例如 CREATE/UPDATE/DELETE 操作 - 這就是 Hibernate 非常適合的地方。另一方面,您有一個讀取數(shù)據(jù)的查詢服務(wù)。在這里,JOOQ 表現(xiàn)出色。與 Hibernate 相比,它使得構(gòu)建復(fù)雜查詢和優(yōu)化它們變得更加容易。

JOOQ 中的 DAO 怎么樣?

這是真的。 JOOQ 允許您生成包含用于從數(shù)據(jù)庫獲取實體的標準查詢的 DAO。您甚至可以用您的方法擴展這些 DAO。此外,JOOQ 將生成可以使用 setter 填充的實體(類似于 Hibernate),并傳遞給 DAO 中的插入或更新方法。這不是像Spring Data嗎?

對于簡單的情況,這確實可行。然而,它與手動實現(xiàn)存儲庫沒有太大區(qū)別。問題類似:

  1. 實體不會有任何關(guān)系:沒有ManyToOne,沒有OneToMany。只是數(shù)據(jù)庫列,這使得編寫業(yè)務(wù)邏輯變得更加困難。
  2. 實體是單獨生成的。您無法將它們組織成繼承層次結(jié)構(gòu)。
  3. 實體與 DAO 一起生成的事實意味著您無法按照自己的意愿修改它們。例如,用值對象替換字段、添加與另一個實體的關(guān)系或?qū)⒆侄畏纸M到可嵌入中是不可能的,因為重新生成實體將覆蓋您的更改。是的,您可以配置生成器以稍微不同的方式創(chuàng)建實體,但自定義選項是有限的(并且不如自己編寫代碼那么方便)。

所以,如果你想構(gòu)建一個復(fù)雜的領(lǐng)域模型,你必須手動完成。如果沒有 Hibernate,映射的責(zé)任將完全落在您身上。當然,使用 JOOQ 比 JDBI 更愉快,但這個過程仍然是勞動密集型的。

甚至 JOOQ 的創(chuàng)建者 Lukas Eder 在他的博客中也提到,DAO 被添加到庫中是因為它是一種流行的模式,而不是因為他一定推薦使用它們。

結(jié)論

感謝您閱讀這篇文章。我是 Hibernate 的忠實粉絲,認為它是一個優(yōu)秀的框架。不過,我知道有些人可能會覺得 JOOQ 更方便。我文章的要點是 Hibernate 和 JOOQ 不是競爭對手。如果這些工具帶來價值,甚至可以在同一產(chǎn)品中共存。

如果您對內(nèi)容有任何意見或反饋,我很樂意討論。祝你度過富有成效的一天!

資源

  1. JDBI
  2. 交易腳本
  3. 領(lǐng)域模型
  4. 我的文章 – 使用 Spring Boot 和 Hibernate 的豐富域模型
  5. 存儲庫模式
  6. 值對象
  7. JPA 嵌入式
  8. JPA 動態(tài)更新
  9. CQRS
  10. Lukas Eder:去 DAO 還是不去 DAO

以上是JOOQ 不是 Hibernate 的替代品。他們解決不同的問題的詳細內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

hashmap和hashtable之間的區(qū)別? hashmap和hashtable之間的區(qū)別? Jun 24, 2025 pm 09:41 PM

HashMap與Hashtable的區(qū)別主要體現(xiàn)在線程安全、null值支持及性能方面。1.線程安全方面,Hashtable是線程安全的,其方法大多為同步方法,而HashMap不做同步處理,非線程安全;2.null值支持上,HashMap允許一個null鍵和多個null值,Hashtable則不允許null鍵或值,否則拋出NullPointerException;3.性能方面,HashMap因無同步機制效率更高,Hashtable因每次操作加鎖性能較低,推薦使用ConcurrentHashMap替

為什么我們需要包裝紙課? 為什么我們需要包裝紙課? Jun 28, 2025 am 01:01 AM

Java使用包裝類是因為基本數(shù)據(jù)類型無法直接參與面向?qū)ο蟛僮?,而實際需求中常需對象形式;1.集合類只能存儲對象,如List利用自動裝箱存儲數(shù)值;2.泛型不支持基本類型,必須使用包裝類作為類型參數(shù);3.包裝類可表示null值,用于區(qū)分未設(shè)置或缺失的數(shù)據(jù);4.包裝類提供字符串轉(zhuǎn)換等實用方法,便于數(shù)據(jù)解析與處理,因此在需要這些特性的場景下,包裝類不可或缺。

什么是接口中的靜態(tài)方法? 什么是接口中的靜態(tài)方法? Jun 24, 2025 pm 10:57 PM

StaticmethodsininterfaceswereintroducedinJava8toallowutilityfunctionswithintheinterfaceitself.BeforeJava8,suchfunctionsrequiredseparatehelperclasses,leadingtodisorganizedcode.Now,staticmethodsprovidethreekeybenefits:1)theyenableutilitymethodsdirectly

JIT編譯器如何優(yōu)化代碼? JIT編譯器如何優(yōu)化代碼? Jun 24, 2025 pm 10:45 PM

JIT編譯器通過方法內(nèi)聯(lián)、熱點檢測與編譯、類型推測與去虛擬化、冗余操作消除四種方式優(yōu)化代碼。1.方法內(nèi)聯(lián)減少調(diào)用開銷,將頻繁調(diào)用的小方法直接插入調(diào)用處;2.熱點檢測識別高頻執(zhí)行代碼并集中優(yōu)化,節(jié)省資源;3.類型推測收集運行時類型信息實現(xiàn)去虛擬化調(diào)用,提升效率;4.冗余操作消除根據(jù)運行數(shù)據(jù)刪除無用計算和檢查,增強性能。

什么是實例初始器塊? 什么是實例初始器塊? Jun 25, 2025 pm 12:21 PM

實例初始化塊在Java中用于在創(chuàng)建對象時運行初始化邏輯,其執(zhí)行先于構(gòu)造函數(shù)。它適用于多個構(gòu)造函數(shù)共享初始化代碼、復(fù)雜字段初始化或匿名類初始化場景,與靜態(tài)初始化塊不同的是它每次實例化時都會執(zhí)行,而靜態(tài)初始化塊僅在類加載時運行一次。

變量的最終關(guān)鍵字是什么? 變量的最終關(guān)鍵字是什么? Jun 24, 2025 pm 07:29 PM

InJava,thefinalkeywordpreventsavariable’svaluefrombeingchangedafterassignment,butitsbehaviordiffersforprimitivesandobjectreferences.Forprimitivevariables,finalmakesthevalueconstant,asinfinalintMAX_SPEED=100;wherereassignmentcausesanerror.Forobjectref

什么是工廠模式? 什么是工廠模式? Jun 24, 2025 pm 11:29 PM

工廠模式用于封裝對象創(chuàng)建邏輯,使代碼更靈活、易維護、松耦合。其核心答案是:通過集中管理對象創(chuàng)建邏輯,隱藏實現(xiàn)細節(jié),支持多種相關(guān)對象的創(chuàng)建。具體描述如下:工廠模式將對象創(chuàng)建交給專門的工廠類或方法處理,避免直接使用newClass();適用于多類型相關(guān)對象創(chuàng)建、創(chuàng)建邏輯可能變化、需隱藏實現(xiàn)細節(jié)的場景;例如支付處理器中通過工廠統(tǒng)一創(chuàng)建Stripe、PayPal等實例;其實現(xiàn)包括工廠類根據(jù)輸入?yún)?shù)決定返回的對象,所有對象實現(xiàn)共同接口;常見變體有簡單工廠、工廠方法和抽象工廠,分別適用于不同復(fù)雜度的需求。

什么是類型鑄造? 什么是類型鑄造? Jun 24, 2025 pm 11:09 PM

類型轉(zhuǎn)換有兩種:隱式和顯式。1.隱式轉(zhuǎn)換自動發(fā)生,如將int轉(zhuǎn)為double;2.顯式轉(zhuǎn)換需手動操作,如使用(int)myDouble。需要類型轉(zhuǎn)換的情況包括處理用戶輸入、數(shù)學(xué)運算或函數(shù)間傳遞不同類型的值時。需要注意的問題有:浮點數(shù)轉(zhuǎn)整數(shù)會截斷小數(shù)部分、大類型轉(zhuǎn)小類型可能導(dǎo)致數(shù)據(jù)丟失、某些語言不允許直接轉(zhuǎn)換特定類型。正確理解語言的轉(zhuǎn)換規(guī)則有助于避免錯誤。

See all articles