10、DDD分層架構

????????微服務架構模型有很多種,例如洋蔥架構、CQRS和六邊形架構等。雖然這些架構模式提出的時代和背景不同,但其核心理念都是為了設計出“高內聚,低耦合”的微服務,輕松實現微服務的架構演進。DDD分層架構的出現,使微服務的架構邊界變得越來越清晰,在微服務架構模型中,占有非常重要的位置。那DDD分層架構到底是什么樣?DDD分層架構如何推動架構演進?我們該怎么轉向DDD分層架構?本章將重點解決這些問題 。

1、什么是DDD分層架構

DDD分層架構其實也在不斷發展和演進。早期的DDD分層架構是一種各層都依賴于基礎層的傳統四層架構,后來這種四層架構進一步優化,實現了各層對基礎層的解耦和依賴倒置。

在最早的傳統四層架構中,基礎層被其他層依賴,位于最核心的位置,是其他各層依賴的核心。但實際上領域層才是軟件的核心,所以這種依賴關系是有問題的。后來就采用了依賴倒置設計,各層服務通過倉儲接口訪問基礎層,從而優化了傳統的DDD四層架構,實現了DDD各層對基礎層的解耦 。

我們本章要重點講解的就是優化后的DDD分層架構。DDD分層架構中包含四層,從上到下依次是:用戶接口層、應用層、領域層和基礎層

1.1 用戶接口層

在很多描述DDD用戶接口層的文章中,對用戶接口層的解釋通常都是這樣的:“用戶接口層負責向用戶顯示信息和解釋用戶指令,這里的用戶可能是用戶、程序、自動化測試和批處理腳本等。”但隨著微服務架構的盛行,大多數應用都采用了前后端分離的設計模式。為了連接前端應用和后端微服務,于是又出現了API網關 。

結合洋蔥模型和端口適配器架構模型,我在這里稍微拓展一下用戶接口層的作用。在微服務面向不同前端應用時,同樣的一段業務邏輯,可能由于渠道不同,而在前端展示的頁面要素不同,因此要求后端微服務返回的數據結果會不同。例如在面向內部員工的PC端應用時,可能要求返回某些對象的全部屬性的數據,而在面向外部客戶的移動端應用時,可能只需要返回幾個關鍵屬性的數據就可以了。

為了避免暴露微服務的核心業務邏輯,防止數據外泄,不能將后端數據直接暴露給前端應用。為此,可以在用戶接口層引入數據傳輸對象(DTO)和門面接口(Facade Interface),通過這些適配器來提供靈活的數據接口,滿足不同前端應用的需求 。

1.2 應用層

應用層主要負責服務的組合和編排,實現業務邏輯。應用服務通過調用領域層的功能來處理用戶請求,并將處理結果返回給用戶。應用層的設計需要關注以下幾個方面:

  • 服務編排:根據業務需求,調用多個領域服務,實現業務功能。
  • 事務管理:管理業務操作的事務,確保數據一致性。
  • 安全控制:處理用戶權限和身份驗證,確保只有合法用戶可以執行操作 。

應用層通常通過應用服務(Application Services)來實現。應用服務是應用層的核心組件,負責處理具體的業務操作。例如,訂單服務的實現可能如下:

public?class?OrderApplicationService?{private?final?OrderRepository orderRepository;private?final?PaymentService paymentService;public?OrderApplicationService(OrderRepository orderRepository, PaymentService paymentService)?{this.orderRepository = orderRepository;this.paymentService = paymentService;}public?void?placeOrder(OrderDTO orderDTO)?{Order?order?=?new?Order(orderDTO);orderRepository.save(order);paymentService.processPayment(order.getPaymentDetails());}public?OrderDTO?getOrder(String orderId)?{Order?order?=?orderRepository.findById(orderId);return?new?OrderDTO(order);}
}
1.3 領域層

領域層是DDD分層架構的核心,負責處理系統的業務邏輯。領域層包含領域模型和領域服務,通過對領域對象和領域行為的建模,實現業務需求 。

領域層的組成

領域層通常包含以下組件:

  • 實體(Entity):具有唯一標識符的對象,表示業務中的關鍵概念。
  • 值對象(Value Object):無唯一標識符的對象,表示業務中的描述性概念。
  • 聚合(Aggregate):一組相關對象的集合,以聚合根(Aggregate Root)為唯一入口。
  • 領域服務(Domain Service):處理跨實體的業務邏輯。
  • 倉儲(Repository):負責實體的持久化和檢索 。
領域層的職責
  • 建模業務邏輯:通過實體、值對象和聚合等模型來表示業務邏輯。
  • 執行業務操作:通過領域服務執行復雜的業務操作。
  • 維護數據一致性:確保領域模型的狀態在業務操作后保持一致 。

領域層的實現需要結合具體的業務需求進行設計。以下是一個簡單的領域層實現示例:

public?class?Order?{private?OrderId id;private?List<OrderItem> items;private?OrderStatus status;public?Order(OrderId id, List<OrderItem> items)?{this.id = id;this.items = items;this.status = OrderStatus.CREATED;}public?void?addItem(OrderItem item)?{items.add(item);}public?void?removeItem(OrderItem item)?{items.remove(item);}public?void?place()?{if?(items.isEmpty()) {throw?new?IllegalStateException("Cannot place an order with no items.");}this.status = OrderStatus.PLACED;}// getters and other methods
}
1.4 基礎層

基礎層提供系統運行所需的技術支持和基礎服務。基礎層的設計需要考慮系統的性能、可靠性和可擴展性。

基礎層的職責
  • 數據持久化:負責將領域對象持久化到數據庫中。
  • 消息傳遞:處理系統內外部的消息傳遞,如事件總線、消息隊列等。
  • 第三方集成:與外部系統或服務集成,如支付網關、郵件服務等 。

基礎層的實現通常涉及數據庫訪問、消息中間件、外部服務調用等。以下是一個基礎設施層的簡單實現示例:

public?class?JpaOrderRepository?implements?OrderRepository?{private?final?EntityManager entityManager;public?JpaOrderRepository(EntityManager entityManager)?{this.entityManager = entityManager;}@Overridepublic?void?save(Order order)?{entityManager.persist(order);}@Overridepublic?Order?findById(OrderId id)?{return?entityManager.find(Order.class, id);}
}
1.5 DDD分層架構的重要原則

DDD分層架構有一個重要的依賴原則:“每層只能與位于其下方的層發生耦合”。根據耦合的緊密程度,可以分為兩種架構模式:嚴格分層架構和松散分層架構 。

嚴格分層架構

嚴格分層架構要求每一層只能依賴于其下層的接口。這種設計使得系統的各個部分可以獨立演進,但也可能導致較多的層間調用和性能開銷。

松散分層架構

松散分層架構允許上層直接訪問底層的某些服務或資源,從而減少層間調用的開銷。這種設計在某些性能敏感的場景中非常有效,但需要小心管理依賴關系,避免系統變得難以維護。

2、DDD分層架構如何推動架構演進

業務和技術不斷變化,領域模型也會隨之演進,從而影響微服務的功能和邊界。通過DDD分層架構,我們可以實現領域模型和微服務的同步演進,推動微服務架構的演進 。

2.1 微服務架構的演進

在微服務架構的演進過程中,DDD分層架構提供了一種清晰的模型,通過明確各層的職責和邊界,使得系統的擴展和維護更加便捷。各層之間通過接口進行通信,實現了服務的高內聚、低耦合。

2.2 微服務內服務的演進

在微服務內部,服務的演進可以通過領域模型的重構和優化來實現。通過引入新的領域對象和服務,改進現有的業務邏輯,確保系統能夠靈活應對業務需求的變化。

3、三層架構如何演進到DDD分層架構

傳統企業應用大多是單體架構,而單體架構多采用三層架構。三層架構可以部分解決程序內代碼間調用復雜、代碼職責不清的問題,但這種分層是邏輯概念,在物理上它仍然是集中式架構,所以并不適合分布式微服務架構 。

其實,DDD分層架構內的基本要素和三層架構類似,只不過在DDD分層架構中,這些要素被重新歸類,劃分到了不同的層,確定了層與層之間的交互規則和職責邊界。在三層架構向DDD分層架構演進時,主要變化發生在業務邏輯層和數據訪問層 。

業務邏輯層的變化

DDD分層架構對三層架構的業務邏輯層進行了更清晰的劃分,改善了三層架構核心業務邏輯混亂、代碼改動相互影響大的問題。DDD分層架構將三層架構業務邏輯層的業務邏輯拆分到了應用層和領域層,分別以應用服務和領域服務等形式存在。應用服務實現服務的組合和編排,領域服務完成核心領域邏輯,應用服務可以快速響應前端業務和流程的變化,而領域層則更加專注領域模型和實現領域邏輯 。

數據訪問層的變化

數據訪問層的變化主要發生在數據訪問層和基礎層之間。三層架構數據訪問采用DAO方式,而DDD分層架構對數據庫等基礎資源訪問時采用了倉儲設計模式,領域層可以通過倉儲接口訪問基礎資源的實現邏輯。這樣,通過依賴倒置實現了各層對基礎資源的解耦。原來三層架構的第三方工具包、驅動、Common、Utility、Config等通用的、公共的基礎資源統一放到了基礎層 。

另外,DDD分層架構在用戶接口層引入了DTO和facade接口,可以給前端應用提供更靈活的數據和接口適配能力 。

4、 本章小結

DDD分層架構是微服務設計和開發的核心框架。通過用戶接口層、應用層、領域層和基礎層這些層次劃分,可以明確微服務內各層的職能,劃定各領域對象的邊界,確定各領域對象的依賴和協作方式 。

傳統企業架構向DDD分層架構的轉變,可以通過重構業務邏輯層和數據訪問層,采用領域驅動設計的原則和方法,逐步實現系統的演進和優化 。

================================

DDD分層架構詳解

領域驅動設計(DDD,Domain-Driven Design)是一種設計方法論,旨在通過緊密結合業務領域和軟件設計來解決復雜業務問題。DDD提倡從業務需求出發,建立清晰的領域模型,并根據該模型設計系統架構。在DDD的實現中,分層架構是關鍵的設計模式之一。本文將詳細探討DDD分層架構的各個方面,包括其基本概念、各層職責、實現策略及其在實際項目中的應用。

1. DDD分層架構的歷史與演變

DDD分層架構最早的形式是一種各層都依賴于基礎層的傳統四層架構。在這種架構中,基礎層位于核心位置,其他各層依賴于基礎層。然而,隨著軟件架構的不斷發展,這種依賴關系逐漸暴露出問題。為了優化架構設計,依賴倒置原則被引入,各層通過接口訪問基礎層,實現了對基礎層的解耦。

1.1 分層架構的演變

分層架構的演變經歷了多個階段,主要包括三層架構、傳統四層架構和優化后的四層架構。

  1. 三層架構:傳統的三層架構包括表示層、業務邏輯層和數據訪問層。這種架構可以部分解決代碼職責不清的問題,但在物理上仍然是集中式架構,不適合分布式微服務架構。

  2. 傳統四層架構:傳統四層架構在三層架構的基礎上增加了基礎層,各層都依賴于基礎層。然而,這種設計并沒有充分考慮領域層的重要性,導致依賴關系不合理。

  3. 優化后的四層架構:優化后的四層架構通過引入依賴倒置原則,各層通過倉儲接口訪問基礎層,實現了對基礎層的解耦,明確了領域層的核心地位。

2. DDD分層架構的組成

DDD分層架構通常包括四層,從上到下依次是:用戶接口層、應用層、領域層和基礎層。每一層都有明確的職責和邊界,彼此之間通過接口進行通信。

  1. 用戶接口層(User Interface Layer):負責接收用戶的輸入和返回處理結果。

  2. 應用層(Application Layer):負責服務的組合和編排,實現業務邏輯。

  3. 領域層(Domain Layer):包含領域模型和領域邏輯,是系統的核心,負責實現核心業務邏輯。

  4. 基礎層(Infrastructure Layer):提供通用的技術和基礎服務,包括數據持久化、消息傳遞等。

2.1 用戶接口層

用戶接口層是系統與外部交互的部分,負責處理用戶的輸入并將處理結果返回給用戶。用戶接口層通過API網關連接前端應用和后端微服務。

2.1.1 用戶接口層的職責
  • 接收用戶輸入:通過API接收前端或其他系統的請求。

  • 展示處理結果:將應用層處理的結果通過API返回給前端或其他系統。

  • 輸入驗證:對用戶輸入的數據進行初步驗證,確保數據格式和內容的合法性。

2.1.2 用戶接口層的實現

用戶接口層通常通過RESTful API或GraphQL等技術實現。例如:

@RestController
@RequestMapping("/orders")
public class OrderController {private final OrderApplicationService orderApplicationService;public OrderController(OrderApplicationService orderApplicationService) {this.orderApplicationService = orderApplicationService;}@PostMappingpublic ResponseEntity<Void> placeOrder(@RequestBody OrderDTO orderDTO) {orderApplicationService.placeOrder(orderDTO);return ResponseEntity.status(HttpStatus.CREATED).build();}@GetMapping("/{id}")public ResponseEntity<OrderDTO> getOrder(@PathVariable String id) {OrderDTO orderDTO = orderApplicationService.getOrder(id);return ResponseEntity.ok(orderDTO);}
}
2.2 應用層

應用層負責協調用戶接口層和領域層,執行應用邏輯。應用層不包含領域邏輯,只負責調用領域層的功能,處理用戶請求并返回結果。

2.2.1 應用層的職責
  • 服務編排:根據業務需求,調用多個領域服務,實現業務功能。

  • 事務管理:管理業務操作的事務,確保數據一致性。

  • 安全控制:處理用戶權限和身份驗證,確保只有合法用戶可以執行操作。

2.2.2 應用層的實現

應用層通常通過應用服務(Application Services)來實現。應用服務是應用層的核心組件,負責處理具體的業務操作。以下是一個典型的應用服務實現示例:

public class OrderApplicationService {private final OrderRepository orderRepository;private final PaymentService paymentService;public OrderApplicationService(OrderRepository orderRepository, PaymentService paymentService) {this.orderRepository = orderRepository;this.paymentService = paymentService;}public void placeOrder(OrderDTO orderDTO) {Order order = new Order(orderDTO);orderRepository.save(order);paymentService.processPayment(order.getPaymentDetails());}public OrderDTO getOrder(String orderId) {Order order = orderRepository.findById(orderId);return new OrderDTO(order);}
}
2.3 領域層

領域層是DDD分層架構的核心,負責處理系統的業務邏輯。領域層包含領域模型和領域服務,通過對領域對象和領域行為的建模,實現業務需求。

2.3.1 領域層的組成

領域層通常包含以下組件:

  • 實體(Entity):具有唯一標識符的對象,表示業務中的關鍵概念。

  • 值對象(Value Object):無唯一標識符的對象,表示業務中的描述性概念。

  • 聚合(Aggregate):一組相關對象的集合,以聚合根(Aggregate Root)為唯一入口。

  • 領域服務(Domain Service):處理跨實體的業務邏輯。

  • 倉儲(Repository):負責實體的持久化和檢索。

2.3.2 領域層的職責
  • 建模業務邏輯:通過實體、值對象和聚合等模型來表示業務邏輯。

  • 執行業務操作:通過領域服務執行復雜的業務操作。

  • 維護數據一致性:確保領域模型的狀態在業務操作后保持一致。

2.3.3 領域層的實現

領域層的實現需要結合具體的業務需求進行設計。以下是一個簡單的領域層實現示例:

public class Order {private OrderId id;private List<OrderItem> items;private OrderStatus status;public Order(OrderId id, List<OrderItem> items) {this.id = id;this.items = items;this.status = OrderStatus.CREATED;}public void addItem(OrderItem item) {items.add(item);}public void removeItem(OrderItem item) {items.remove(item);}public void place() {if (items.isEmpty()) {throw new IllegalStateException("Cannot place an order with no items.");}this.status = OrderStatus.PLACED;}// getters and other methods
}
2.4 基礎層

基礎層提供系統運行所需的技術支持和基礎服務。基礎層的設計需要考慮系統的性能、可靠性和可擴展性。

2.4.1 基礎層的職責
  • 數據持久化:負責將領域對象持久化到數據庫中。

  • 消息傳遞:處理系統內外部的消息傳遞,如事件總線、消息隊列等。

  • 第三方集成:與外部系統或服務集成,如支付網關、郵件服務等。

2.4.2 基礎層的實現

基礎層的實現通常涉及數據庫訪問、消息中間件、外部服務調用等。以下是一個基礎設施層的簡單實現示例:

public class JpaOrderRepository implements OrderRepository {private final EntityManager entityManager;public JpaOrderRepository(EntityManager entityManager) {this.entityManager = entityManager;}@Overridepublic void save(Order order) {entityManager.persist(order);}@Overridepublic Order findById(OrderId id) {return entityManager.find(Order.class, id);}
}
3. DDD分層架構的重要原則

DDD分層架構有一個重要的依賴原則:“每層只能與位于其下方的層發生耦合”。根據耦合的緊密程度,可以分為兩種架構模式:嚴格分層架構和松散分層架構。

3.1 嚴格分層架構

嚴格分層架構要求每一層只能依賴于其下層的接口。這種設計使得系統的各個部分可以獨

立演進,但也可能導致較多的層間調用和性能開銷。

3.2 松散分層架構

松散分層架構允許上層直接訪問底層的某些服務或資源,從而減少層間調用的開銷。這種設計在某些性能敏感的場景中非常有效,但需要小心管理依賴關系,避免系統變得難以維護。

4. DDD分層架構的優勢

DDD分層架構通過明確各層的職責和邊界,實現了系統的高內聚、低耦合,具有以下優勢:

  • 提高系統可維護性:每一層都有明確的職責和邊界,代碼更加清晰,便于維護和擴展。

  • 增強系統靈活性:通過分層設計,可以在不影響其他層的情況下,對某一層進行修改和優化。

  • 促進團隊協作:不同層次的職責劃分明確,團隊成員可以專注于各自負責的層次,提高開發效率。

5. DDD分層架構的實踐

在實際項目中,DDD分層架構的應用需要結合具體的業務需求和技術環境進行調整。以下是一些實踐建議:

5.1 選擇合適的分層策略

根據系統的復雜度和業務需求,選擇合適的分層策略。對于小型項目,可以采用簡化的三層架構;對于大型項目,則可以采用完整的四層架構。

5.2 遵循依賴倒置原則

在DDD分層架構中,低層不應該依賴于高層,高層應該通過接口依賴于低層。這一原則通過依賴倒置(Dependency Inversion Principle, DIP)來實現,有助于降低層之間的耦合。

5.3 結合CQRS模式

命令查詢責任分離(Command Query Responsibility Segregation, CQRS)是一種常見的設計模式,將寫操作和讀操作分離,以提高系統的性能和擴展性。在DDD分層架構中,可以結合CQRS模式,實現更加靈活的架構設計。

5.4 應用事件驅動架構

事件驅動架構(Event-Driven Architecture, EDA)是一種基于事件的系統設計模式,適用于處理復雜業務邏輯和高并發場景。在DDD分層架構中,可以通過領域事件和事件總線,實現各層之間的解耦和異步處理。

5.5 實現自動化測試

自動化測試是確保系統質量的重要手段。在DDD分層架構中,可以通過單元測試、集成測試和端到端測試等多種方式,對各層進行全面測試,確保系統的穩定性和可靠性。

6. 案例分析:電商系統的DDD分層架構

為了更好地理解DDD分層架構的應用,以下以一個電商系統為例,進行詳細的案例分析。

6.1 需求分析

一個典型的電商系統需要處理以下業務需求:

  • 用戶管理:注冊、登錄、用戶信息管理等。

  • 商品管理:商品的增刪改查、分類管理、庫存管理等。

  • 訂單管理:訂單創建、支付、配送、訂單狀態管理等。

  • 促銷管理:優惠券、折扣活動等。

6.2 系統架構設計

根據以上需求,可以設計一個基于DDD分層架構的電商系統。系統架構圖如下:

+--------------------+
|  用戶接口層        |
+--------------------+
|  應用層            |
+--------------------+
|  領域層            |
+--------------------+
|  基礎設施層        |
+--------------------+
6.3 各層職責與實現

用戶接口層:負責處理用戶的注冊、登錄、瀏覽商品、下單等操作。可以使用前端框架(如React、Vue)實現。

應用層:負責協調用戶接口層和領域層,處理用戶請求并返回結果。包括用戶服務、商品服務、訂單服務等。

public class OrderApplicationService {private final OrderRepository orderRepository;private final PaymentService paymentService;public OrderApplicationService(OrderRepository orderRepository, PaymentService paymentService) {this.orderRepository = orderRepository;this.paymentService = paymentService;}public void placeOrder(OrderDTO orderDTO) {Order order = new Order(orderDTO);orderRepository.save(order);paymentService.processPayment(order.getPaymentDetails());}public OrderDTO getOrder(String orderId) {Order order = orderRepository.findById(orderId);return new OrderDTO(order);}
}

領域層:包含用戶、商品、訂單等領域模型及其業務邏輯。通過實體、值對象、聚合等模型表示業務邏輯。

public class Order {private OrderId id;private List<OrderItem> items;private OrderStatus status;public Order(OrderId id, List<OrderItem> items) {this.id = id;this.items = items;this.status = OrderStatus.CREATED;}public void addItem(OrderItem item) {items.add(item);}public void removeItem(OrderItem item) {items.remove(item);}public void place() {if (items.isEmpty()) {throw new IllegalStateException("Cannot place an order with no items.");}this.status = OrderStatus.PLACED;}// getters and other methods
}

基礎設施層:提供數據持久化、消息傳遞等服務。包括數據庫訪問層、消息隊列等。

public class JpaOrderRepository implements OrderRepository {private final EntityManager entityManager;public JpaOrderRepository(EntityManager entityManager) {this.entityManager = entityManager;}@Overridepublic void save(Order order) {entityManager.persist(order);}@Overridepublic Order findById(OrderId id) {return entityManager.find(Order.class, id);}
}
6.4 應用CQRS和事件驅動架構

在電商系統中,可以結合CQRS和事件驅動架構,實現讀寫操作的分離和事件處理的解耦。

CQRS:將訂單的寫操作和讀操作分離,通過命令總線處理寫操作,通過查詢總線處理讀操作。

事件驅動架構:在訂單創建、支付完成、訂單狀態變更等關鍵操作時,發布領域事件,通過事件總線傳遞給訂閱者,實現各服務之間的異步解耦。

// 訂單創建事件
public class OrderCreatedEvent {private String orderId;private String userId;private LocalDateTime createTime;// 構造函數、getter和setter方法
}// 發布訂單創建事件
public void placeOrder(OrderDTO orderDTO) {Order order = new Order(orderDTO);orderRepository.save(order);OrderCreatedEvent event = new OrderCreatedEvent(order.getId(), order.getUserId(), LocalDateTime.now());eventBus.publish(event);
}// 處理訂單創建事件
public class OrderCreatedEventHandler {@Subscribepublic void handle(OrderCreatedEvent event) {// 處理訂單創建后的業務邏輯}
}
7. 總結

DDD分層架構通過明確各層的職責和邊界,實現了系統的高內聚、低耦合,提高了系統的可維護性和擴展性。在實際項目中,應用DDD分層架構需要結合具體的業務需求和技術環境,選擇合適的分層策略,并結合CQRS和事件驅動架構等設計模式,實現靈活高效的系統設計。

通過對DDD分層架構的深入理解和實踐應用,我們可以構建出更加健壯和靈活的系統,更好地應對復雜業務需求和快速變化的技術環境。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42140.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42140.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42140.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是ThreadLocal以及內存泄漏問題、hash沖突問題

ThreadLocal是什么 ThreadLocal類用來提供線程內部的局部變量 它主要有三大特性&#xff1a; 線程安全: 在多線程并發的場景下保證線程安全傳遞數據&#xff1a;通過ThreadLocal在同一線程傳遞公共變量線程隔離&#xff1a;每個線程的變量都是獨立的&#xff0c;不會互相影響…

這次讓我們從幾個點認識一下Mysql的Innodb

MySQL 的 InnoDB 存儲引擎是 MySQL 默認和最常用的存儲引擎之一。它主要關注的是高可靠性、性能以及完整的事務支持。以下是對 InnoDB 存儲引擎的詳細介紹&#xff1a; 1. 數據庫特性 1.1 事務支持 InnoDB 是完全支持事務的存儲引擎&#xff0c;支持四種主要的事務隔離級別&…

【uniapp-ios】App端與webview端相互通信的方法以及注意事項

前言 在開發中&#xff0c;使用uniapp開發的項目開發效率是極高的&#xff0c;使用一套代碼就能夠同時在多端上線&#xff0c;像筆者之前寫過的使用Flutter端和webview端之間的相互通信方法和問題&#xff0c;這種方式本質上實際上是h5和h5之間的通信&#xff0c;網上有非常多…

ios身份證實名認證接口開發示例助力電商物流實名認證

為了更好的利用貨車資源&#xff0c;也方便企業正常的運送貨物&#xff0c;“互聯網電商”平臺可謂風起云涌。貨車司機和有發貨需求的人們可以在物流平臺注冊&#xff0c;貨車司機接單為有運送需求的用戶提供有償貨運服務。那么&#xff0c;如何讓企業放心的將貨物安心的交予貨…

物聯網實訓室建設可行性報告

一、建設物聯網實訓室的目的和意義 隨著信息技術的快速發展&#xff0c;物聯網&#xff08;IoT&#xff09;已成為推動社會進步和經濟發展的關鍵技術之一。物聯網技術的集成應用&#xff0c;不僅能夠提高生產效率&#xff0c;還能促進智慧城市、智能家居、智能農業等多個領域的…

python04——類(基礎new)

類其實也是一種封裝的思想&#xff0c;類就是把變量、方法等封裝在一起&#xff0c;然后可以通過不同的實例化對其進行調用操作。 1.類的定義 class 類名&#xff1a; 變量a def __init__ (self,參數2&#xff0c;參數2...)&#xff1a;初始化函數&#xff01;&#xff01;&…

vivado DELAY_VALUE_XPHY、DIFF_TERM

延遲_值_XPHY PORT對象上的DELAY_VALUE_XPHY屬性指定要添加的延遲量 Versal XPHY邏輯接口的輸入或輸出路徑。在的早期階段 opt_design在重新生成高級I/O向導IP時 DELAY_VALUE_XPHY值將從PORT復制到的XPHY實例上 輸入或輸出路徑。Vivado設計套件中存在DRCs&#xff0c;以確保 DE…

簡單實現聯系表單Contact Form自動發送郵件

如何實現簡單Contact Form自動郵件功能&#xff1f;怎樣簡單設置&#xff1f; 聯系表單不僅是訪客與網站所有者溝通的橋梁&#xff0c;還可以收集潛在客戶的信息&#xff0c;從而推動業務的發展。AokSend將介紹如何簡單實現一個聯系表單&#xff0c;自動發送郵件的過程&#x…

java Collections類介紹

Java 的 java.util.Collections 類提供了一組靜態方法&#xff0c;用于操作或返回集合&#xff08;如列表、集合和映射&#xff09;。Collections 類是一個實用工具類&#xff0c;旨在為集合提供便捷的算法和操作。以下是對 Collections 類及其常用方法的介紹。 常用方法總結 …

【游戲客戶端】大話slg玩法架構(一)滾動基類

【游戲客戶端】大話slg玩法架構&#xff08;一&#xff09;滾動基類 大家好&#xff0c;我是Lampard家杰~~ 今天我們兌現諾言&#xff0c;給大家分享SLG玩法的實現j架構&#xff0c;關于SLG玩法的介紹可以參考這篇上一篇文章&#xff1a;【游戲客戶端】制作率土之濱Like玩法 PS…

保險理論與實踐

《保險理論與實踐》是由中國保險學會主辦的學術集刊&#xff0c;于2016年1月正式創辦&#xff0c;致力于發表權威、嚴謹、高質量的理論研究、政策研究和實務研究成果&#xff0c;強調學術性與政策性、理論性與實踐性的有機結合。本刊由中國金融出版社公開出版&#xff0c;每月下…

postmessage()在同一域名下,傳遞消息給另一個頁面

這里是同域名下&#xff0c;getmessage.html&#xff08;發送信息&#xff09;傳遞消息給index.html&#xff08;收到信息&#xff0c;并回傳收到信息&#xff09; index.html頁面 <!DOCTYPE html> <html><head><meta http-equiv"content-type"…

機器學習統計學基礎 - 最大似然估計

最大似然估計&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是一種常用的參數估計方法&#xff0c;其基本原理是通過最大化觀測數據出現的概率來尋找最優的參數估計值。具體來說&#xff0c;最大似然估計的核心思想是利用已知的樣本結果&#xff0c;反推最有可能…

Java并發編程工具包(JUC)詳解

在現代軟件開發中&#xff0c;多線程編程是一個不可避免的話題。為了更好地管理和利用多線程&#xff0c;Java提供了一個強大的工具包——java.util.concurrent&#xff08;簡稱JUC&#xff09;。JUC包含了許多用于并發編程的類和接口&#xff0c;幫助開發者高效、安全地處理線…

binutils ifunc 流程圖

上圖是x86 binutils 的流程圖。 函數說明_bfd_x86_elf_link_hash_table_createInit local STT_GNU_IFUNC symbol hash.elf_x86_64_check_relocsAdd support for handling STT_GNU_IFUNC symbols_bfd_elf_x86_get_local_sym_hashFind and/or create a hash entry for local sym…

[Go] 字符串遍歷數據類型問題

字符串遍歷問題 在使用for i,v:range str遍歷字符串時 str[i]是unit8&#xff08;byte&#xff09;類型&#xff0c;返回的是單個字節 字符串在Go中是以字節序列的形式存儲的&#xff0c;而 str[i] 直接訪問了這個字節序列中的第 i 個字節。如果字符串中的字符是單字節的ASCII…

Leetcode—97. 交錯字符串【中等】

2024每日刷題&#xff08;140&#xff09; Leetcode—97. 交錯字符串 2d動規實現代碼 class Solution { public:bool isInterleave(string s1, string s2, string s3) {int m s1.length();int n s2.length();int len s3.length();if(m n ! len) {return false;}vector<…

SpringBoot日常:封裝rabbitmq starter組件

文章目錄 邏輯實現RabbitExchangeEnumRabbitConfigRabbitModuleInfoRabbitModuleInitializerRabbitPropertiesRabbitProducerManagerPOM.xmlspring.factories 功能測試application.yml配置生產者&#xff1a;消費者&#xff1a;測試結果&#xff1a;總結 本章內容主要介紹編寫一…

stm32 USB CDC類虛擬串口初體驗

1. 目標 本文介紹CubeMX生成 USB CDC類虛擬串口工程的操作步驟。 2. 配置流程 時鐘配置 usb外設需要48M時鐘輸入 stm32405使用外部時鐘源HSE,否則配不出來48M時鐘stm32h750內部有一個48M時鐘 stm32f405時鐘配置 stm32h750時鐘配置 Connectivity ->USB_OTG_FS 和 Connect…

GEE代碼實例教程詳解:植被狀況指數(VCI)與干旱監測

簡介 在本篇博客中&#xff0c;我們將使用Google Earth Engine (GEE) 進行植被狀況指數&#xff08;Vegetation Condition Index, VCI&#xff09;的計算和干旱監測。通過MODIS NDVI數據&#xff0c;我們可以評估2001年至2024年間的植被狀況和干旱等級。 背景知識 MODIS NDV…