SpringBoot+FacadePattern:透過統一介面簡化多模組業務

👉 這是一個或許對你有用的社群
🐱 一對一交流/面試小冊/簡歷最佳化/求職解惑,歡迎加入芋道快速開發平臺知識星球。下面是星球提供的部分資料:
👉這是一個或許對你有用的開源專案
國產 Star 破 10w+ 的開源專案,前端包括管理後臺 + 微信小程式,後端支援單體和微服務架構。
功能涵蓋 RBAC 許可權、SaaS 多租戶、資料許可權、商城、支付、工作流、大屏報表、微信公眾號、ERPCRMAI 大模型等等功能:
  • Boot 多模組架構:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 微服務架構:https://gitee.com/zhijiantianya/yudao-cloud
  • 影片教程:https://doc.iocoder.cn
【國內首批】支援 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 雙版本 

概述

外觀設計模式(Facade Pattern)是一種常見的結構型設計模式,它的主要目的是簡化複雜系統的使用。可以把它想象成一個“控制面板”或者“遙控器”,透過這個控制面板,使用者可以輕鬆操作一個複雜的系統,而不需要關心繫統內部是如何運作的。
舉個生活中的例子,想象一下,你家有一臺多功能的家電,比如一臺智慧電視,它不僅能看電視,還能上網、播放影片、控制智慧家居等等。對於電視的操作,你有遙控器,可以透過一些按鈕控制各種功能。
  • 複雜系統: 電視內部的各種硬體(顯示屏、網路模組、聲音系統、處理器等)和軟體(作業系統、應用程式等)。
  • 外觀模式: 遙控器,它將所有複雜的操作集中在幾個按鈕上,使用者只需要按下遙控器上的某個按鈕(比如“開機”或“返回主螢幕”),就能觸發一系列複雜的操作,而不需要了解電視內部的具體工作原理。
基於 Spring Boot + MyBatis Plus + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
  • 專案地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 影片教程:https://doc.iocoder.cn/video/

在程式設計中,外觀模式是如何工作的?

外觀模式透過為複雜系統提供一個簡潔的介面,將複雜的子系統操作封裝在一個統一的外觀類(Facade)中。使用者只需要與外觀類互動,而不需要關心具體的實現細節。
例如,一個複雜系統涉及多個子模組,如果沒有外觀模式,使用者(或程式)在呼叫時,可能需要依次與每個子模組進行互動,呼叫很多方法,導致程式碼非常複雜。透過外觀模式,我們可以將這些操作封裝成一個簡單的方法呼叫,使用者只需要呼叫外觀類的方法即可。
外觀模式的好處
  • 簡化介面: 將複雜的系統封裝起來,提供一個簡單易懂的介面,減少了呼叫者的複雜度。
  • 降低耦合度: 外部系統不需要直接依賴複雜的子系統,只需要依賴外觀類,減少了系統間的依賴。
  • 提高可維護性: 如果系統的內部實現發生變化,外觀類的介面不變,呼叫者不需要修改任何程式碼。
  • 方便擴充套件: 新的子系統可以輕鬆整合,只需要修改外觀類,不影響其他部分。
外觀設計模式的核心思想就是 簡化介面,隱藏複雜性。它提供了一個高層次的介面,簡化了系統的使用,減少了客戶端與複雜子系統之間的耦合度。這種模式非常適用於需要簡化複雜系統、減少外部依賴的場景。
基於 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
  • 專案地址:https://github.com/YunaiV/yudao-cloud
  • 影片教程:https://doc.iocoder.cn/video/

外觀設計模式 UML 類圖

外觀設計模式的 UML 圖 主要展示了外觀類(Facade)如何透過統一的介面與多個子系統進行互動,併為客戶端提供簡化的介面
Client(客戶端): 客戶端透過呼叫外觀類(Facade)的方法來與子系統進行互動,客戶端只需要關注外觀類提供的簡單介面,而不需要直接操作複雜的子系統。
Facade(外觀類): 外觀類提供了一個統一的介面(如 operation()),將複雜的操作委託給不同的子系統。客戶端透過呼叫外觀類的方法來簡化與多個子系統的互動。
Subsystem1, Subsystem2, Subsystem3(子系統類): 這些類代表系統中的各個子模組,每個子系統類都有自己複雜的邏輯方法(如 method1()method2()method3()),但是客戶端不直接呼叫它們,而是透過外觀類來與之互動。

外觀類和子系統的關係

外觀類透過 組合(subsystem1, subsystem2, subsystem3)的方式持有多個子系統的例項。
外觀類的方法(例如 operation())在內部呼叫不同子系統的方法,客戶端只需要呼叫外觀類提供的簡單介面,而不需要直接與多個子系統互動。

優點

  • 簡化介面: 客戶端透過外觀類,避免了直接與多個複雜的子系統打交道。
  • 降低耦合度: 客戶端與多個子系統之間的耦合減少,客戶端只與外觀類互動,而不需要關心子系統的具體實現。
  • 增強可維護性: 如果子系統的實現發生了變化,客戶端無需改動,只需要修改外觀類的實現即可。

案例

在構建大型系統時,業務邏輯通常分散在不同的層次之間,涉及多個功能模組,這些模組之間相互依賴,彼此交織,難以快速理解與維護。例如,一個典型的 線上旅遊預訂系統,其預訂流程可能涉及到如下多個子系統或功能模組:
  • 航班查詢: 根據使用者輸入的起點、終點和日期查詢可用航班。
  • 酒店預定: 查詢目標地點的酒店併為使用者提供預定選項。
  • 旅遊套餐推薦: 根據使用者偏好推薦相關旅遊套餐。
  • 支付介面對接: 與第三方支付介面對接完成支付。
這些環節需要在多個服務、多個方法之間傳遞資料與控制流。假設需求有所變動,新增了一個業務流程或修改了現有流程,往往需要在不同的層次之間修改程式碼,甚至可能會影響到系統的其他部分。

外觀模式在複雜業務中的應用

外觀模式(Facade Pattern) 是一種結構型設計模式,它提供了一個統一的介面,來訪問子系統中的一組介面。外觀模式透過為複雜子系統提供一個簡單的介面,隱藏了系統的複雜性,使得外部呼叫者只需要關注簡潔明瞭的介面,而不必關心其內部複雜的實現細節。簡言之,外觀模式就是在複雜的業務子系統上加一個“控制面板”(外觀類),透過簡單的按鈕(外觀類的方法)控制複雜的“機器”運轉。
在一個典型的 線上旅遊預訂系統 中,預訂業務涉及到多個子系統和服務。透過外觀模式,我們可以將所有涉及的業務邏輯統一封裝在一個外觀類中,而上層業務只需要與該外觀類互動即可,無需關心其內部的實現細節。

實戰運用

以下程式碼簡化了複雜的業務邏輯,重點體會

1. 專案搭建與基礎配置

首先,建立一個 Spring Boot 專案,加入必要的依賴:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>

org.springframework.boot

</groupId>
<artifactId>

spring-boot-starter-web

</artifactId>
</dependency>

<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>

org.springframework.boot

</groupId>
<artifactId>

spring-boot-starter-data-jpa

</artifactId>
</dependency>

<!-- H2 Database (for simplicity) -->
<dependency>
<groupId>

com.h2database

</groupId>
<artifactId>

h2

</artifactId>
<scope>

runtime

</scope>
</dependency>
</dependencies>

然後,我們建立相應的實體類,例如 Flight、Hotel 和 Package,併為它們建立相應的 Repository 介面:
@Entity
publicclassFlight

{

@Id
private

 Long id;

private

 String flightNumber;

private

 String departure;

private

 String arrival;

// Getters and Setters

}

@Repository
publicinterfaceFlightRepositoryextendsJpaRepository<FlightLong

{

}

2. 構建子系統元件

在旅遊系統中,涉及到多個子系統服務,例如航班查詢、酒店預定、旅遊套餐推薦等。我們為這些子系統服務建立相應的元件類:
  • 航班服務
@Service
publicclassFlightService

{

public List<Flight> findAvailableFlights(String departure, String arrival, LocalDate date)

{

// 實際查詢資料庫或呼叫外部航班API,此處簡化邏輯

        System.out.println(

"查詢航班:"

 + departure + 

" 到 "

 + arrival + 

",日期:"

 + date);

return

 List.of(

new

 Flight(

1L

"AA123"

, departure, arrival));

    }

}

  • 酒店服務
@Service
publicclassHotelService

{

public List<Hotel> findAvailableHotels(String location, LocalDate checkInDate, LocalDate checkOutDate)

{

// 查詢酒店資訊

        System.out.println(

"查詢酒店:"

 + location + 

",入住:"

 + checkInDate + 

",退房:"

 + checkOutDate);

return

 List.of(

new

 Hotel(

1L

"Hotel California"

, location));

    }

}

  • 旅遊套餐服務
@Service
publicclassPackageService

{

public List<TourPackage> recommendPackages(String destination)

{

// 推薦套餐

        System.out.println(

"推薦旅遊套餐:"

 + destination);

return

 List.of(

new

 TourPackage(

1L

"Paris Special"

, destination));

    }

}

3. 建立外觀類

接下來,我們建立一個 BookingFacade 類,將多個子系統的功能集中封裝在一個外觀類中:
@Service
publicclassBookingFacade

{

privatefinal

 FlightService flightService;

privatefinal

 HotelService hotelService;

privatefinal

 PackageService packageService;

publicBookingFacade(FlightService flightService, HotelService hotelService, PackageService packageService)

{

this

.flightService = flightService;

this

.hotelService = hotelService;

this

.packageService = packageService;

    }

publicbooleanbookTravel

(String departure, String arrival, LocalDate flightDate,

                               String hotelLocation, LocalDate checkIn, LocalDate checkOut,

                               String destination)

{

// 查詢航班

        List<Flight> flights = flightService.findAvailableFlights(departure, arrival, flightDate);

if

 (flights.isEmpty()) {

returnfalse

;

        }

// 查詢酒店

        List<Hotel> hotels = hotelService.findAvailableHotels(hotelLocation, checkIn, checkOut);

if

 (hotels.isEmpty()) {

returnfalse

;

        }

// 推薦旅遊套餐

        List<TourPackage> packages = packageService.recommendPackages(destination);

if

 (packages.isEmpty()) {

returnfalse

;

        }

returntrue

;

    }

}

4. 在 Controller 中使用外觀類

在 Spring Boot 的 Controller 層中,我們可以直接使用 BookingFacade 來簡化業務邏輯的呼叫:
@RestController
@RequestMapping

(

"/bookings"

)

publicclassBookingController

{

privatefinal

 BookingFacade bookingFacade;

publicBookingController(BookingFacade bookingFacade)

{

this

.bookingFacade = bookingFacade;

    }

@PostMapping
public ResponseEntity<String> bookTravel(@RequestBody TravelRequest travelRequest)

{

boolean

 success = bookingFacade.bookTravel(travelRequest.getDeparture(),

                                                  travelRequest.getArrival(),

                                                  travelRequest.getFlightDate(),

                                                  travelRequest.getHotelLocation(),

                                                  travelRequest.getCheckIn(),

                                                  travelRequest.getCheckOut(),

                                                  travelRequest.getDestination());

if

 (success) {

return

 ResponseEntity.ok(

"旅遊預定成功"

);

        }

return

 ResponseEntity.badRequest().body(

"旅遊預定失敗"

);

    }

}

透過以上設計,BookingController 只需要關注如何處理使用者請求,而具體的業務邏輯(如航班查詢、酒店預定、套餐推薦)都已經被封裝在 BookingFacade 類中。無論如何修改或擴充套件預定業務,我們只需要在外觀類中進行修改,其他地方的程式碼不需要做任何變動。

小結

外觀模式為系統提供了統一且簡潔的介面,同時隱藏了底層複雜的業務邏輯。而 Spring Boot 強大的依賴注入(DI)特性,使得各個服務的整合變得更加靈活與易於管理。
透過這種設計方式,我們能夠:
  • 降低程式碼耦合度: 將複雜的子系統封裝起來,暴露簡單的介面,降低了不同模組之間的依賴關係。
  • 提升程式碼可維護性: 對於新增需求或業務變更,我們只需要在外觀類中進行修改,而不用在多個地方重複修改。
  • 增強開發效率: 業務邏輯的模組化和統一化,使得開發人員能更加專注於業務實現,而不是處理複雜的互動關係。

歡迎加入我的知識星球,全面提升技術能力。
👉 加入方式,長按”或“掃描”下方二維碼噢
星球的內容包括:專案實戰、面試招聘、原始碼解析、學習路線。
文章有幫助的話,在看,轉發吧。
謝謝支援喲 (*^__^*)

相關文章