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

Java開發(fā)中的常用設(shè)計(jì)模式實(shí)戰(zhàn)應(yīng)用小結(jié)

 更新時(shí)間:2026年03月07日 14:52:35   作者:beata  
本文詳細(xì)介紹了Java開發(fā)中5個(gè)最常用的設(shè)計(jì)模式:?jiǎn)卫J?、工廠方法模式、觀察者模式、策略模式和適配器模式,并結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景提供了完整的Java代碼示例,感興趣的朋友跟隨小編一起看看吧

在Java開發(fā)中,設(shè)計(jì)模式是解決常見軟件設(shè)計(jì)問題的可復(fù)用解決方案。它們不是代碼模板,而是經(jīng)驗(yàn)總結(jié),能顯著提升代碼的可維護(hù)性、可擴(kuò)展性和可重用性。根據(jù)《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書,設(shè)計(jì)模式分為創(chuàng)建型、結(jié)構(gòu)型和行為型三大類。本文將深入剖析5個(gè)最常用的設(shè)計(jì)模式,結(jié)合真實(shí)業(yè)務(wù)場(chǎng)景,提供完整可運(yùn)行的Java代碼示例。拒絕“紙上談兵”,只講實(shí)戰(zhàn)!

一、為什么需要設(shè)計(jì)模式?—— 從痛點(diǎn)出發(fā)

想象一個(gè)場(chǎng)景:

一個(gè)電商系統(tǒng)需要支持多種支付方式(微信、支付寶、信用卡),但支付邏輯分散在多個(gè)Service中。當(dāng)新增支付方式時(shí),必須修改大量代碼,導(dǎo)致維護(hù)成本飆升,甚至引發(fā)新Bug。

這就是缺乏設(shè)計(jì)模式的典型問題:代碼緊耦合、擴(kuò)展性差。設(shè)計(jì)模式的核心價(jià)值在于:將變化封裝起來(lái),讓系統(tǒng)對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。

二、實(shí)戰(zhàn)解析:5個(gè)高頻設(shè)計(jì)模式

1. 單例模式(Singleton)—— 確保全局唯一實(shí)例

核心思想:保證一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問點(diǎn)。
適用場(chǎng)景:數(shù)據(jù)庫(kù)連接池、日志管理器、配置中心(避免重復(fù)初始化資源)。
為什么重要:避免資源浪費(fèi)(如頻繁創(chuàng)建數(shù)據(jù)庫(kù)連接),保證狀態(tài)一致性。

實(shí)戰(zhàn)代碼:數(shù)據(jù)庫(kù)連接池

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
 * 單例模式:線程安全的數(shù)據(jù)庫(kù)連接池
 * 使用雙重檢查鎖定(DCL)避免多線程問題
 */
public class DatabaseConnectionPool {
    // volatile確??梢娦?,防止指令重排
    private static volatile DatabaseConnectionPool instance;
    private Connection connection;
    private DatabaseConnectionPool() throws SQLException {
        // 初始化數(shù)據(jù)庫(kù)連接(實(shí)際生產(chǎn)中會(huì)使用連接池框架如HikariCP)
        this.connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "user", "password");
    }
    public static DatabaseConnectionPool getInstance() throws SQLException {
        if (instance == null) {
            synchronized (DatabaseConnectionPool.class) {
                if (instance == null) {
                    instance = new DatabaseConnectionPool();
                }
            }
        }
        return instance;
    }
    public Connection getConnection() {
        return connection;
    }
    // 業(yè)務(wù)使用示例
    public static void main(String[] args) {
        try {
            DatabaseConnectionPool pool = DatabaseConnectionPool.getInstance();
            Connection conn = pool.getConnection();
            System.out.println("Database connection established: " + conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

關(guān)鍵點(diǎn)

  • volatile + 雙重檢查鎖定:解決多線程下的實(shí)例初始化問題。
  • 避免:直接使用 public static DatabaseConnectionPool instance = new DatabaseConnectionPool();(無(wú)法控制初始化時(shí)機(jī))。

2. 工廠方法模式(Factory Method)—— 解耦對(duì)象創(chuàng)建

核心思想:定義創(chuàng)建對(duì)象的接口,但讓子類決定實(shí)例化哪個(gè)類。
適用場(chǎng)景:框架設(shè)計(jì)(如JDBC驅(qū)動(dòng)、Spring Bean管理)、需要靈活擴(kuò)展的場(chǎng)景。
為什么重要:客戶端代碼不依賴具體類,只需依賴抽象接口。

實(shí)戰(zhàn)代碼:支付方式工廠

/**
 * 工廠方法模式:支付方式工廠
 * 業(yè)務(wù)場(chǎng)景:電商系統(tǒng)支持微信、支付寶、信用卡支付
 */
// 抽象產(chǎn)品:支付接口
interface Payment {
    void pay(int amount);
}
// 具體產(chǎn)品:微信支付
class WeChatPay implements Payment {
    @Override
    public void pay(int amount) {
        System.out.println("WeChat Pay: " + amount + "元");
    }
}
// 具體產(chǎn)品:支付寶
class Alipay implements Payment {
    @Override
    public void pay(int amount) {
        System.out.println("Alipay: " + amount + "元");
    }
}
// 工廠:根據(jù)類型創(chuàng)建支付對(duì)象
class PaymentFactory {
    public Payment createPayment(String type) {
        switch (type.toLowerCase()) {
            case "wechat":
                return new WeChatPay();
            case "alipay":
                return new Alipay();
            default:
                throw new IllegalArgumentException("Unsupported payment type: " + type);
        }
    }
}
// 業(yè)務(wù)調(diào)用(無(wú)需修改代碼即可新增支付方式)
public class PaymentService {
    private PaymentFactory factory = new PaymentFactory();
    public void processPayment(String paymentType, int amount) {
        Payment payment = factory.createPayment(paymentType);
        payment.pay(amount);
    }
    public static void main(String[] args) {
        PaymentService service = new PaymentService();
        service.processPayment("wechat", 100); // 輸出:WeChat Pay: 100元
        service.processPayment("alipay", 200);  // 輸出:Alipay: 200元
    }
}

關(guān)鍵點(diǎn)

  • 擴(kuò)展性:新增支付方式只需實(shí)現(xiàn)Payment接口 + 修改工廠,無(wú)需修改PaymentService
  • 對(duì)比:若用if-else硬編碼,新增支付方式需修改PaymentService,違反開閉原則。

3. 觀察者模式(Observer)—— 實(shí)現(xiàn)事件驅(qū)動(dòng)

核心思想:定義對(duì)象間一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象狀態(tài)改變時(shí),所有依賴它的對(duì)象都收到通知并自動(dòng)更新。
適用場(chǎng)景:GUI事件處理、消息訂閱(如訂單狀態(tài)變更通知、實(shí)時(shí)股價(jià)推送)。
為什么重要:解耦發(fā)布者與訂閱者,避免循環(huán)依賴。

實(shí)戰(zhàn)代碼:訂單狀態(tài)通知系統(tǒng)

import java.util.ArrayList;
import java.util.List;
/**
 * 觀察者模式:訂單狀態(tài)通知
 * 業(yè)務(wù)場(chǎng)景:用戶下單后,短信、郵件、APP推送同時(shí)通知
 */
// 主題(被觀察者)
interface OrderSubject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
// 觀察者接口
interface Observer {
    void update(String orderStatus);
}
// 訂單實(shí)體(被觀察者)
class Order implements OrderSubject {
    private List<Observer> observers = new ArrayList<>();
    private String status;
    public void setStatus(String status) {
        this.status = status;
        notifyObservers(); // 狀態(tài)變更時(shí)通知所有觀察者
    }
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(status);
        }
    }
}
// 具體觀察者:短信通知
class SmsObserver implements Observer {
    @Override
    public void update(String status) {
        System.out.println("SMS: 訂單狀態(tài)更新為 " + status);
    }
}
// 具體觀察者:郵件通知
class EmailObserver implements Observer {
    @Override
    public void update(String status) {
        System.out.println("Email: 訂單狀態(tài)更新為 " + status);
    }
}
// 業(yè)務(wù)使用
public class OrderNotificationSystem {
    public static void main(String[] args) {
        Order order = new Order();
        // 注冊(cè)觀察者
        order.registerObserver(new SmsObserver());
        order.registerObserver(new EmailObserver());
        // 更新訂單狀態(tài)(自動(dòng)觸發(fā)通知)
        order.setStatus("Shipped"); // 輸出:SMS: 訂單狀態(tài)更新為 Shipped
                                 //       Email: 訂單狀態(tài)更新為 Shipped
    }
}

關(guān)鍵點(diǎn)

  • 解耦Order 不知道具體觀察者實(shí)現(xiàn),只需維護(hù)Observer列表。
  • 擴(kuò)展性:新增通知方式(如APP推送)只需實(shí)現(xiàn)Observer,無(wú)需修改Order。

4. 策略模式(Strategy)—— 封裝算法族

核心思想:定義一系列算法,將每個(gè)算法封裝起來(lái),使它們可以互相替換。
適用場(chǎng)景:排序算法、支付方式、促銷策略(如滿減、折扣)。
為什么重要:避免if-else分支爆炸,提高算法復(fù)用性。

實(shí)戰(zhàn)代碼:促銷策略引擎

/**
 * 策略模式:促銷策略
 * 業(yè)務(wù)場(chǎng)景:電商大促,支持滿減、折扣、無(wú)優(yōu)惠三種策略
 */
// 策略接口
interface PromotionStrategy {
    double calculateDiscount(double originalPrice);
}
// 具體策略:滿減(滿100減20)
class FullReduction implements PromotionStrategy {
    @Override
    public double calculateDiscount(double originalPrice) {
        return originalPrice > 100 ? originalPrice - 20 : originalPrice;
    }
}
// 具體策略:折扣(85折)
class Discount implements PromotionStrategy {
    @Override
    public double calculateDiscount(double originalPrice) {
        return originalPrice * 0.85;
    }
}
// 上下文:促銷引擎
class PromotionEngine {
    private PromotionStrategy strategy;
    public void setStrategy(PromotionStrategy strategy) {
        this.strategy = strategy;
    }
    public double applyPromotion(double price) {
        return strategy.calculateDiscount(price);
    }
}
// 業(yè)務(wù)使用
public class PromotionDemo {
    public static void main(String[] args) {
        PromotionEngine engine = new PromotionEngine();
        // 設(shè)置滿減策略
        engine.setStrategy(new FullReduction());
        System.out.println("FullReduction: " + engine.applyPromotion(120)); // 輸出: 100.0
        // 切換為折扣策略
        engine.setStrategy(new Discount());
        System.out.println("Discount: " + engine.applyPromotion(120)); // 輸出: 102.0
    }
}

關(guān)鍵點(diǎn)

  • 動(dòng)態(tài)切換:運(yùn)行時(shí)通過(guò)setStrategy切換策略,無(wú)需重啟服務(wù)。
  • 避免分支:相比if (type == "full"),代碼更簡(jiǎn)潔、可測(cè)試。

5. 適配器模式(Adapter)—— 消除接口不兼容

核心思想:將一個(gè)類的接口轉(zhuǎn)換成客戶期望的另一個(gè)接口。
適用場(chǎng)景:集成第三方API(如支付SDK)、遺留系統(tǒng)改造。
為什么重要:復(fù)用已有代碼,無(wú)需修改原始類。

實(shí)戰(zhàn)代碼:支付SDK適配器

/**
 * 適配器模式:支付SDK適配
 * 業(yè)務(wù)場(chǎng)景:接入新支付公司(如PayPal)的SDK,但原有系統(tǒng)使用老接口
 */
// 目標(biāo)接口(系統(tǒng)期望的)
interface OldPaymentGateway {
    void processPayment(double amount);
}
// 適配器:將PayPalSDK適配到OldPaymentGateway
class PayPalAdapter implements OldPaymentGateway {
    private PayPalSDK payPalSDK;
    public PayPalAdapter(PayPalSDK payPalSDK) {
        this.payPalSDK = payPalSDK;
    }
    @Override
    public void processPayment(double amount) {
        // PayPalSDK的接口與OldPaymentGateway不一致
        payPalSDK.makePayment(amount);
    }
}
// 第三方SDK(無(wú)法修改)
class PayPalSDK {
    public void makePayment(double amount) {
        System.out.println("PayPal SDK: Processing payment of " + amount);
    }
}
// 業(yè)務(wù)使用(無(wú)需修改原有代碼)
public class PaymentAdapterDemo {
    public static void main(String[] args) {
        OldPaymentGateway gateway = new PayPalAdapter(new PayPalSDK());
        gateway.processPayment(50.0); // 輸出:PayPal SDK: Processing payment of 50.0
    }
}

關(guān)鍵點(diǎn)

  • 解耦:系統(tǒng)調(diào)用OldPaymentGateway,適配器處理SDK差異。
  • 擴(kuò)展性:接入新支付公司只需新增適配器(如AlipayAdapter),不修改核心邏輯。

三、設(shè)計(jì)模式的正確使用原則

  1. 不要為了用而用:如果場(chǎng)景簡(jiǎn)單(如只創(chuàng)建1個(gè)對(duì)象),直接new即可,避免過(guò)度設(shè)計(jì)。
  2. 優(yōu)先使用標(biāo)準(zhǔn)模式:如Spring框架已內(nèi)置工廠、單例等模式,優(yōu)先復(fù)用而非自己實(shí)現(xiàn)。
  3. 結(jié)合業(yè)務(wù)場(chǎng)景:策略模式適合算法變化,觀察者適合事件驅(qū)動(dòng),勿混淆。
  4. 代碼可讀性 > 模式數(shù)量:清晰的代碼比堆砌模式更重要。

經(jīng)典名言
“設(shè)計(jì)模式是經(jīng)驗(yàn)的結(jié)晶,不是代碼的枷鎖。” —— 《設(shè)計(jì)模式》作者 Erich Gamma

四、總結(jié):設(shè)計(jì)模式是“工具”,不是“目的”

模式適用場(chǎng)景代碼復(fù)雜度業(yè)務(wù)價(jià)值
單例資源唯一實(shí)例(DB連接)資源復(fù)用、狀態(tài)一致
工廠方法對(duì)象創(chuàng)建邏輯復(fù)雜(支付)降低耦合、擴(kuò)展靈活
觀察者事件通知(訂單狀態(tài))解耦發(fā)布者與訂閱者
策略算法動(dòng)態(tài)切換(促銷)避免分支爆炸、提升復(fù)用
適配器接口不兼容(第三方集成)快速集成、減少修改

在實(shí)際項(xiàng)目中,90%的場(chǎng)景用這5種模式即可覆蓋。記?。涸O(shè)計(jì)模式不是銀彈,而是讓代碼更“像人”——清晰、可理解、易維護(hù)。

最后建議

  1. 從項(xiàng)目中已有的問題出發(fā),選擇最匹配的模式。
  2. 閱讀Spring、Guava等開源框架的源碼,學(xué)習(xí)模式的實(shí)戰(zhàn)應(yīng)用。
  3. 用單元測(cè)試驗(yàn)證模式效果(如策略模式切換策略時(shí)的正確性)。

參考資料

  • 《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》(GoF)
  • Spring Framework源碼(工廠、單例實(shí)現(xiàn))
  • Java 8+特性(Lambda、Stream)與設(shè)計(jì)模式的結(jié)合(如策略模式 + 函數(shù)式接口)

本文所有代碼已通過(guò)JDK 11+編譯測(cè)試,可直接運(yùn)行。設(shè)計(jì)模式不是終點(diǎn),而是構(gòu)建健壯系統(tǒng)的起點(diǎn)。在Java開發(fā)中,用好設(shè)計(jì)模式,讓代碼“說(shuō)話”而非“打架”!

到此這篇關(guān)于Java開發(fā)中的常用設(shè)計(jì)模式實(shí)戰(zhàn)應(yīng)用小結(jié)的文章就介紹到這了,更多相關(guān)java常用設(shè)計(jì)模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java將Object轉(zhuǎn)換為數(shù)組的代碼

    Java將Object轉(zhuǎn)換為數(shù)組的代碼

    這篇文章主要介紹了Java將Object轉(zhuǎn)換為數(shù)組的情況,今天在使用一個(gè)別人寫的工具類,這個(gè)工具類,主要是判空操作,包括集合、數(shù)組、Map等對(duì)象是否為空的操作,需要的朋友可以參考下
    2022-09-09
  • SpringCloud?客戶端Ribbon負(fù)載均衡的實(shí)現(xiàn)方法

    SpringCloud?客戶端Ribbon負(fù)載均衡的實(shí)現(xiàn)方法

    Ribbon 是 Netflix 提供的一個(gè)基于 Http 和 TCP 的客戶端負(fù)載均衡工具,且已集成在 Eureka 依賴中,這篇文章主要介紹了SpringCloud?客戶端Ribbon負(fù)載均衡的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2022-06-06
  • Java獲取文件路徑的幾種方式匯總

    Java獲取文件路徑的幾種方式匯總

    本文介紹了使用Java處理文件路徑的方法,包括使用java.io.File、java.nio.file.Paths類處理本地文件和類路徑資源,以及在Web應(yīng)用中獲取路徑的方法,它還提供了最佳實(shí)踐和注意事項(xiàng),如使用現(xiàn)代化的路徑處理方式和跨平臺(tái)兼容性,需要的朋友可以參考下
    2026-04-04
  • Java時(shí)間戳類Instant的使用詳解

    Java時(shí)間戳類Instant的使用詳解

    這篇文章主要為大家詳細(xì)介紹了Java中時(shí)間戳類Instant的使用方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-09-09
  • spring boot集成mongodb的增刪改查的示例代碼

    spring boot集成mongodb的增刪改查的示例代碼

    這篇文章主要介紹了spring boot集成mongodb的增刪改查的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換

    Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換

    這篇文章主要介紹了Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Java數(shù)組創(chuàng)建的3種方法6種寫法代碼示例

    Java數(shù)組創(chuàng)建的3種方法6種寫法代碼示例

    這篇文章主要給大家介紹了關(guān)于Java數(shù)組創(chuàng)建的3種方法6種寫法,在Java中我們可以使用關(guān)鍵字new來(lái)創(chuàng)建一個(gè)數(shù)組,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • 關(guān)于java 圖形驗(yàn)證碼的解決方法

    關(guān)于java 圖形驗(yàn)證碼的解決方法

    本篇文章小編為大家介紹,在java中,使用圖形驗(yàn)證碼的解決方法。需要的朋友參考下
    2013-04-04
  • Java泛型的繼承和實(shí)現(xiàn)操作示例

    Java泛型的繼承和實(shí)現(xiàn)操作示例

    這篇文章主要介紹了Java泛型的繼承和實(shí)現(xiàn)操作,結(jié)合實(shí)例形式分析了java泛型類的繼承以及泛型接口的實(shí)現(xiàn)相關(guān)操作技巧,需要的朋友可以參考下
    2019-08-08
  • 使用Java實(shí)現(xiàn)TXT到Word文檔的格式轉(zhuǎn)換

    使用Java實(shí)現(xiàn)TXT到Word文檔的格式轉(zhuǎn)換

    在Java開發(fā)中,我們經(jīng)常需要將純文本文件(TXT)的內(nèi)容轉(zhuǎn)換為格式規(guī)范的Word文檔(DOCX),下面就跟隨小編一起來(lái)看看具體的實(shí)現(xiàn)方法吧
    2025-09-09

最新評(píng)論

泌阳县| 阜平县| 工布江达县| 筠连县| 枣强县| 抚远县| 襄樊市| 北海市| 香河县| 青冈县| 石狮市| 义马市| 重庆市| 加查县| 威宁| 丰宁| 清徐县| 东丰县| 东乌珠穆沁旗| 鹤山市| 株洲市| 兴山县| 陈巴尔虎旗| 民勤县| 马龙县| 涟源市| 博兴县| 宜兴市| 屏东县| 盐边县| 济阳县| 铁岭县| 托里县| 德钦县| 蓝山县| 霍林郭勒市| 遵义市| 海门市| 斗六市| 宜昌市| 灵寿县|