泛型設計模式實踐

學海無涯,志當存遠。燃心礪志,奮進不輟。

愿諸君得此雞湯,如沐春風,事業有成。

若覺此言甚善,煩請賜贊一枚,共勵學途,同鑄輝煌!

為解決在設計框架或庫時遇到的類型安全問題,或者處理多態集合時的挑戰。
希望優化代碼結構,減少重復,提高類型安全。
需要結合常見的設計模式,比如工廠模式、策略模式等,展示泛型如何在這些模式中發揮作用。常見的泛型設計模式,比如類型安全的異構容器、泛型單例工廠、策略模式中的泛型應用,以及構建器模式。
需要具體說明每個模式的應用場景、實現方式和優勢。
例如,類型安全的異構容器使用Class對象作為鍵,存儲不同類型的實例,
這樣可以在編譯時保證類型安全,避免運行時錯誤。痛點難點,比如處理不同類型數據時的強制轉換,或者如何避免使用Object類型帶來的類型不安全。
此時,展示如何通過泛型消除顯式轉換,提升代碼的可讀性和安全性。
例如,使用泛型方法替代重載,減少代碼重復。橋接方法在類型擦除中的作用,以及如何利用反射獲取泛型信息,
比如通過ParameterizedType來動態獲取類型參數。
但要注意反射的使用場景和限制,比如類型擦除后的信息保留情況。實際項目中應用這些設計模式,結合相應的代碼示例,并解釋每個步驟的設計考慮。
比如,在工廠模式中使用泛型創建不同產品類型的實例,避免多個工廠類的問題。
或者,在策略模式中使用泛型接口,使策略實現能夠處理不同類型的數據。潛在的問題和最佳實踐,比如避免過度使用泛型導致代碼復雜化,或者如何處理類型擦除帶來的限制。
例如,在創建泛型數組時,使用通配符類型或@SuppressWarnings注解,并解釋為何需要謹慎處理。最后,總結這些設計模式如何綜合提升代碼的靈活性和可維護性,強調類型安全的重要性,
以及在維護和擴展代碼時的便利。

目錄

一、類型安全的異構容器(Type-Safe Heterogeneous Container)

二、泛型工廠模式(Generic Factory)

三、策略模式 + 泛型(Generic Strategy)

四、構建器模式 + 泛型(Generic Builder)

五、模板方法模式 + 泛型(Generic Template Method)

六、責任鏈模式 + 泛型

七、觀察者模式 + 泛型

八、應用建議

1.類型邊界明確化 :始終為泛型參數定義明確的邊界

2.避免類型擦除問題 :在需要保留類型信息時使用Class對象

3.合理使用通配符 :提高API靈活性

總結:泛型設計模式的核心價值


在Java開發中,結合泛型與設計模式可以顯著提升代碼的類型安全性復用性可維護性。以下是幾種典型的泛型設計模式實踐,通過具體場景說明其優勢:


一、類型安全的異構容器(Type-Safe Heterogeneous Container)

場景:需要在一個容器中存儲和獲取不同類型的對象,同時保證類型安全
實現:使用Class<T>對象作為鍵,動態關聯類型與值。

public class TypeSafeContainer {private Map<Class<?>, Object> container = new HashMap<>();public <T> void put(Class<T> type, T instance) {container.put(type, instance);}public <T> T get(Class<T> type) {return type.cast(container.get(type));}// 使用示例public static void main(String[] args) {TypeSafeContainer container = new TypeSafeContainer();container.put(String.class, "Hello");container.put(Integer.class, 42);String str = container.get(String.class);  // 無需強制轉換Integer num = container.get(Integer.class); // 類型安全}
}

優勢

  • 避免使用Object類型和強制轉換,消除ClassCastException風險。

  • 通過Class<T>類型檢查確保鍵值對類型一致性。


二、泛型工廠模式(Generic Factory)

場景:創建不同類型對象時,避免為每個類型編寫重復的工廠類。
實現:通過泛型接口統一工廠方法,結合反射動態實例化對象

public interface GenericFactory<T> {T create();
}// 實現通用工廠(基于反射)
public class ReflectionFactory<T> implements GenericFactory<T> {private Class<T> type;public ReflectionFactory(Class<T> type) {this.type = type;}@Overridepublic T create() {try {return type.getDeclaredConstructor().newInstance();} catch (Exception e) {throw new RuntimeException(e);}}
}// 使用示例
public class Main {public static void main(String[] args) {GenericFactory<String> stringFactory = new ReflectionFactory<>(String.class);String str = stringFactory.create();  // 創建空字符串GenericFactory<ArrayList<?>> listFactory = new ReflectionFactory<>(ArrayList.class);ArrayList<?> list = listFactory.create(); // 創建空列表}
}
public interface GenericFactory<T> {T create();
}// 具體產品工廠實現
public class ProductFactory<T extends Product> implements GenericFactory<T> {private Class<T> productClass;public ProductFactory(Class<T> productClass) {this.productClass = productClass;}@Overridepublic T create() {try {return productClass.newInstance();} catch (Exception e) {throw new RuntimeException("創建產品失敗", e);}}
}

優勢

  • 一個工廠類支持所有類型,減少代碼冗余。

  • 通過類型參數約束,確保工廠產出對象類型正確。


三、策略模式 + 泛型(Generic Strategy)

場景:定義可復用的算法策略,支持不同類型數據的處理邏輯。
實現:泛型接口聲明策略,具體實現類處理特定類型。

// 策略接口(泛型化)
public interface ValidationStrategy<T> {boolean validate(T data);
}// 具體策略:校驗字符串非空
public class StringNonEmptyStrategy implements ValidationStrategy<String> {@Overridepublic boolean validate(String data) {return data != null && !data.isEmpty();}
}// 具體策略:校驗數值范圍
public class NumberRangeStrategy implements ValidationStrategy<Integer> {private final int min;private final int max;public NumberRangeStrategy(int min, int max) {this.min = min;this.max = max;}@Overridepublic boolean validate(Integer data) {return data >= min && data <= max;}
}// 使用示例
public class Validator {public static <T> boolean validate(T data, ValidationStrategy<T> strategy) {return strategy.validate(data);}public static void main(String[] args) {boolean isValidString = validate("test", new StringNonEmptyStrategy()); // trueboolean isValidNumber = validate(15, new NumberRangeStrategy(10, 20)); // true}
}
public interface PricingStrategy<T extends Product> {BigDecimal calculatePrice(T product, int quantity);
}// 具體策略實現
public class DiscountPricingStrategy<T extends DiscountableProduct> implements PricingStrategy<T> {@Overridepublic BigDecimal calculatePrice(T product, int quantity) {return product.getOriginalPrice().multiply(product.getDiscountRate()).multiply(new BigDecimal(quantity));}
}

優勢

  • 策略邏輯與數據類型解耦,可復用性強

  • 編譯器檢查策略與數據類型的匹配,避免運行時錯誤。


四、構建器模式 + 泛型(Generic Builder)

場景:構建復雜對象時,支持鏈式調用和類型安全的屬性賦值
實現:使用泛型遞歸定義構建器,確保方法鏈的連貫性。

public abstract class Animal {private final String name;private final int age;protected Animal(Builder<?> builder) {this.name = builder.name;this.age = builder.age;}// 泛型構建器(遞歸類型定義)public abstract static class Builder<T extends Builder<T>> {private String name;private int age;public T name(String name) {this.name = name;return self();}public T age(int age) {this.age = age;return self();}abstract Animal build();protected abstract T self(); // 返回當前構建器實例}
}// 具體子類:Dog
public class Dog extends Animal {private final String breed;private Dog(DogBuilder builder) {super(builder);this.breed = builder.breed;}// 具體構建器public static class DogBuilder extends Builder<DogBuilder> {private String breed;public DogBuilder breed(String breed) {this.breed = breed;return this;}@Overridepublic Dog build() {return new Dog(this);}@Overrideprotected DogBuilder self() {return this;}}
}// 使用示例
Dog dog = new Dog.DogBuilder().name("Buddy").age(3).breed("Golden Retriever").build();
public class ProductBuilder<T extends Product> {private T product;public ProductBuilder(Supplier<T> supplier) {this.product = supplier.get();}public ProductBuilder<T> withName(String name) {product.setName(name);return this;}public ProductBuilder<T> withPrice(BigDecimal price) {product.setPrice(price);return this;}public T build() {return product;}
}

優勢

  • 鏈式調用語法清晰,IDE自動補全支持良好。

  • 子類構建器方法返回具體類型,避免類型轉換。


五、模板方法模式 + 泛型(Generic Template Method)

場景:定義算法骨架,允許子類實現特定步驟,同時支持不同類型的數據處理。
實現:抽象類使用泛型定義算法流程,子類指定具體類型。

public abstract class DataProcessor<T> {// 模板方法(算法骨架)public final void process() {T data = loadData();validate(data);transform(data);save(data);}protected abstract T loadData();protected abstract void validate(T data);protected abstract void transform(T data);protected abstract void save(T data);
}// 具體實現:處理CSV數據
public class CsvProcessor extends DataProcessor<List<String[]>> {@Overrideprotected List<String[]> loadData() {// 從文件加載CSV數據return Arrays.asList(new String[]{"Alice", "30"}, new String[]{"Bob", "25"});}@Overrideprotected void validate(List<String[]> data) {data.forEach(row -> {if (row.length != 2) throw new IllegalArgumentException("Invalid CSV format");});}@Overrideprotected void transform(List<String[]> data) {data.replaceAll(row -> new String[]{row[0].toUpperCase(), row[1]});}@Overrideprotected void save(List<String[]> data) {System.out.println("Saving processed CSV: " + data);}
}
public abstract class DataProcessor<T, R> {public final R process(T input) {validate(input);R result = doProcess(input);postProcess(result);return result;}protected abstract R doProcess(T input);protected void validate(T input) {// 默認驗證邏輯}protected void postProcess(R result) {// 默認后處理邏輯}
}

優勢

  • 復用算法流程,子類只需關注具體類型邏輯。

  • 類型參數明確每個步驟的數據類型,減少錯誤。


六、責任鏈模式 + 泛型

線性處理流程

場景:- 電商訂單處理流程 :訂單驗證→庫存檢查→支付處理→物流分配
???????????- 審批工作流 :不同級別的審批人處理不同類型的申請
? ? ? ? ? ?- 數據處理管道 :數據清洗→轉換→驗證→持久化
實現:定義抽象類中下一次調用參數next, 調用時實現鏈路調用

// 基礎訂單處理器
public abstract class OrderProcessor<T extends Order> {private OrderProcessor<T> next;public OrderProcessor<T> linkWith(OrderProcessor<T> next) {this.next = next;return next;}public abstract boolean process(T order);protected boolean processNext(T order) {return next == null ? true : next.process(order);}
}// 具體處理器實現
public class InventoryChecker extends OrderProcessor<PurchaseOrder> {@Overridepublic boolean process(PurchaseOrder order) {if (!checkInventory(order)) {return false;}return processNext(order);}private boolean checkInventory(PurchaseOrder order) {// 庫存檢查邏輯}
}
public interface OrderHandler<T extends Order> {void handle(T order);void setNext(OrderHandler<T> next);
}// 基礎抽象類
public abstract class AbstractOrderHandler<T extends Order> implements OrderHandler<T> {private OrderHandler<T> next;@Overridepublic void setNext(OrderHandler<T> next) {this.next = next;}protected void handleNext(T order) {if (next != null) {next.handle(order);}}
}
// 電商訂單處理系統(責任鏈)
// 構建處理鏈
OrderProcessor<Order> processorChain = new OrderValidator().linkWith(new PaymentProcessor()).linkWith(new ShippingProcessor());// 處理訂單
processorChain.process(order);

優勢

  • 類型安全 :確保每個處理器只處理特定類型的訂單

  • 靈活擴展 :可動態添加新的處理器而不影響現有邏輯

  • 解耦 :每個處理器只需關注自己的職責范圍

注意:處理鏈中所有處理器類型一致、鏈長度影響性能、單向傳遞


七、觀察者模式 + 泛型

事件通知場景

場景:- 電商事件通知?:訂單狀態變更、庫存預警、支付成功等事件
???????????- 用戶行為追蹤 :記錄用戶瀏覽、點擊、購買等行為
? ? ? ? ? ?- 系統監控 :CPU使用率、內存占用等指標變化通知
實現:抽象類使用泛型定義算法流程,子類指定具體類型。?

public class GenericEventBus<T> {private Map<Class<? extends T>, List<Consumer<? extends T>>> listeners = new ConcurrentHashMap<>();public <E extends T> void subscribe(Class<E> eventType, Consumer<E> listener) {listeners.computeIfAbsent(eventType, k -> new ArrayList<>()).add(listener);}@SuppressWarnings("unchecked")public <E extends T> void publish(E event) {List<Consumer<? extends T>> eventListeners = listeners.get(event.getClass());if (eventListeners != null) {eventListeners.forEach(listener -> ((Consumer<E>) listener).accept(event));}}
}// 事件定義
public class OrderEvent {private String orderId;// 其他字段...
}
public class EventPublisher<T> {private List<Consumer<T>> listeners = new ArrayList<>();public void subscribe(Consumer<T> listener) {listeners.add(listener);}public void publish(T event) {listeners.forEach(listener -> listener.accept(event));}
}
//  庫存預警系統(觀察者)
// 創建事件總線
GenericEventBus<InventoryEvent> eventBus = new GenericEventBus<>();// 訂閱事件
eventBus.subscribe(LowStockEvent.class, event -> {// 發送預警郵件emailService.sendLowStockAlert(event.getProductId());
});// 發布事件
eventBus.publish(new LowStockEvent(productId, currentStock));

優勢

  • 類型精確匹配 :訂閱者只會收到其訂閱的特定類型事件

  • 性能優化 :通過事件類型分類,減少不必要的通知

  • 編譯時檢查 :避免運行時類型轉換錯誤

  • 多事件類型支持 :一個事件總線可處理多種相關事件類型

注意:訂閱者數量影響性能、可處理多種相關事件類型、發布者無法控制訂閱者執行、一對多廣播


八、應用建議

1.類型邊界明確化 :始終為泛型參數定義明確的邊界
public class UserService<T extends User & Serializable> {// 同時繼承User和實現Serializable
}

2.避免類型擦除問題 :在需要保留類型信息時使用Class對象
public class JpaRepository<T, ID> {private Class<T> entityClass;public JpaRepository(Class<T> entityClass) {this.entityClass = entityClass;}
}

3.合理使用通配符 :提高API靈活性
public static void copy(List<? extends Product> src, List<? super Product> dest) {dest.addAll(src);
}

總結:泛型設計模式的核心價值

  1. 類型安全:編譯器檢查類型匹配,減少運行時錯誤。

  2. 代碼復用:通過泛型抽象通用邏輯,避免重復代碼。

  3. 可擴展性:新增類型時只需擴展泛型類/接口,無需修改核心邏輯。

  4. 清晰表達意圖:泛型類型參數明確代碼設計目的,提升可讀性。

通過將泛型與設計模式結合,可以創建出既靈活又類型安全的代碼結構,顯著提升代碼的可維護性和可擴展性。每種模式都通過泛型增強了其適用場景,使代碼更加通用而不失類型安全.

在實際項目中,應根據場景選擇合適模式,避免過度泛型化導致代碼復雜度上升。結合Optional<T>Stream API等特性,可進一步構建靈活且健壯的Java應用。

學海無涯,志當存遠。燃心礪志,奮進不輟。

愿諸君得此雞湯,如沐春風,事業有成。

若覺此言甚善,煩請賜贊一枚,共勵學途,同鑄輝煌!

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

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

相關文章

【kafla掃盲】FROM GPT

Kafka 掃盲指南&#xff1a;分布式流處理利器 Apache Kafka 是一個分布式流處理平臺&#xff0c;最早由 LinkedIn 開發&#xff0c;后來開源并捐贈給 Apache 基金會。Kafka 專為高吞吐量、低延遲的實時數據流處理而設計&#xff0c;廣泛用于日志收集、實時分析、消息隊列、流處…

每天五分鐘深度學習框架pytorch:視覺工具包torchvison

本文重點 在pytorch深度學習框架中,torchvision是一個非常優秀的視覺工具包,我們可以使用它加載一些著名的數據集,然后我們可以使用它來加載網絡模型,比如vgg,resnet等等,還可以使用它來預處理一些圖片數據,本節課程我們將學習一下它的使用方式。 torchvision的四部分…

操作系統 第2章節 進程,線程和作業

一:多道程序設計 1-多道程設計的目的 for:提高吞吐量(作業道數/處理時間),我們可以從提高資源的利用率出發 2-單道程序設計缺點: 設備的利用率低,內存的利用率低,處理機的利用率低 比如CPU去訪問內存,CPU空轉.內存等待CPU訪問也是沒有任何操作的.要是有多個東西要去訪問不沖…

位移監測儀,精準測量,專業守護

地質災害如滑坡、泥石流、地面沉降等具有突發性強、破壞性大的特點&#xff0c;傳統人工巡查方式存在效率低、時效性差等缺陷。對人類生命財產構成嚴重威脅&#xff0c;因此需要實時、精準的位移監測手段。地質災害監測預警系統集成了多種傳感器&#xff0c;對地表及地下形變進…

dropout層

從你提供的圖片來看&#xff0c;里面討論了 Dropout 層&#xff0c;讓我為你解釋一下它的工作原理和作用。 Dropout 層是什么&#xff1f; Dropout 是一種常用的正則化技術&#xff0c;用于避免神經網絡的 過擬合&#xff08;overfitting&#xff09;。過擬合是指模型在訓練數…

C++八股 —— vector底層

vector底層為動態數組 類構成 class vector : protected _Vector_base_Vector_base: _M_start&#xff1a;容器元素開始的位置_M_finish&#xff1a;容器元素結束的位置_M_end_of_storage&#xff1a;動態內存最后一個元素的下一個位置 構造函數 無參構造 根據性能優先規則&a…

LLM量化方法:ZeroQuant、LLM.int8()、SmoothQuant、GPTQ、AWQ

文章目錄 TLDR;量化分類量化時機量化粒度ZeroQuant: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers細粒度硬件感知量化低成本逐層知識蒸餾&#xff08;Layer-by-layer Knowledge Distillation, LKD&#xff09; LLM.int8(): 8-bit Matrix…

SIGIR 2025端到端生成式推薦ETEGRec

文章目錄 1. 背景2. 方法2.1 框架圖2.2 問題定義2.3 Item Tokenizer2.4 Generative Recommender2.5 ??Sequence-Item Alignment2.6 ??Preference-Semantic Alignment2.7 交替優化 3. 總結 現階段 GRM 大多是兩階段的模型&#xff0c;第一階段進行內容理解-行為語義對齊&…

STM32CubeMX安裝及使用分享

說是教程&#xff0c;屬實是不敢當&#xff0c;只是把自己覺得較為正式的方式分享給各位&#xff0c;如有問題請提出大家一起討論。 文章目錄 軟件下載軟件安裝軟件使用開發板工程單片機工程單片機工程創建單片機工程配置界面單片機工程具體配置引腳功能配置系統時鐘配置工程配…

MySQL報錯解決過程

我在調試datagrip的時候&#xff0c;顯示拒絕連接&#xff0c;開始的時候&#xff0c;我以為只是服務沒有開啟&#xff0c;結果到后來在網上搜索各種解決辦法無果后&#xff0c;就選擇卸載&#xff0c;卸載之后安裝新的MySQL 以下就是我的解決過程。 如果只是在使用外置軟件&…

動態規劃-62.不同路徑-力扣(LeetCode)

一、題目解析 機器人只能向下或向左&#xff0c;要從Start位置到Finish位置。 二、算法原理 1.狀態表示 我們要求到Finish位置一共有多少種方法&#xff0c;記Finish為[i,j]&#xff0c;此時dp[i,j]表示&#xff1a;到[i,j]位置時&#xff0c;一共有多少種方法&#xff0c;滿…

Qt開發:項目視圖(Item Views)的介紹和使用

文章目錄 一、清單視圖&#xff08;List View&#xff09;1.1 基本概念1.2 使用示例&#xff08;文字列表&#xff09;1.3 圖標文字&#xff08;圖標模式&#xff09;1.4 常用設置1.5 完整示例 二、樹視圖&#xff08;Tree View&#xff09;2.1 基本概念2.2 常用類簡介2.3 快速…

GoWeb開發(基礎)

Go&#xff08;Golang&#xff09;是一種高效、簡潔的編程語言&#xff0c;特別適合Web開發。以下是詳細的Go Web開發指南&#xff0c;涵蓋從基礎到進階的內容。 --- 一、Go Web開發基礎 1. 標準庫 net/http Go 內置 net/http 包&#xff0c;支持快速構建 Web 服務。 - 基本示…

GSENSE2020BSI sCMOS科學級相機主要參數及應用場景

GSENSE2020BSI sCMOS科學級相機是一款面向寬光譜成像需求的高性能科學成像設備&#xff0c;結合了背照式&#xff08;Back-Side Illuminated, BSI&#xff09;CMOS技術與先進信號處理算法&#xff0c;適用于天文觀測、生物醫學成像、工業檢測等領域。以下是其核心特點及技術細節…

【日擼 Java 三百行】Day 9(While語句)

目錄 Day 9&#xff1a;While 語句的基本使用方法 一、基礎知識及案例分析 二、代碼及測試 拓展&#xff1a;流程控制語句專題補充 小結 Day 9&#xff1a;While 語句的基本使用方法 Task&#xff1a; while 語句本質上比 for 更基礎, 因此可以替代后者. 但 for 在很多時候…

React 第三十七節 Router 中 useOutlet Hook的使用介紹以及注意事項

React Router 中的 useOutlet 是 v6 版本新增的 Hook&#xff0c;用于在父路由組件中訪問當前嵌套的子路由元素。它提供了比 <Outlet> 組件更靈活的控制方式&#xff0c;適合需要根據子路由狀態進行動態處理的場景。 一、useOutlet的基本用法 import { useOutlet } fro…

TDengine 在智慧油田領域的應用

簡介 智慧油田&#xff0c;亦稱為數字油田或智能油田&#xff0c;是一種采用尖端信息技術與先進裝備的現代油田開發模式。該模式通過實時更新油氣田層析圖及動態生產數據&#xff0c;顯著提高了油氣田的開發效率與經濟價值。 信息技術在此領域發揮著至關重要的作用&#xff0…

關于AI 大數據模型的基礎知識 雜記

一、LM Studio LM Studio下載地址&#xff1a;LM Studio - Discover, download, and run local LLMshttps://lmstudio.ai/LM Studio是使用electron架構&#xff0c;引用的llama.cpp庫。 下載后的模型存儲于 /User/Admin/.lmstudio/models中。 二、llama.cpp庫下載地址 llam…

2025數維杯數學建模競賽B題完整參考論文(共38頁)(含模型、代碼、數據)

2025數維杯數學建模競賽B題完整參考論文 目錄 摘要 一、問題重述 二、問題分析 三、模型假設 四、定義與符號說明 五、 模型建立與求解 5.1問題1 5.1.1問題1思路分析 5.1.2問題1模型建立 5.1.3問題1求解結果 5.2問題2 5.2.1問題2思路分析 5.2.2問題2…

利用GPT實現油猴腳本—網頁滾動(優化版)

在瀏覽網頁的時候&#xff0c;發現有的網頁沒有直達最前這樣的功能&#xff0c;所有心血來潮利用ChatGPT寫了一個油猴腳本以實現此功能&#xff0c;在網站上出現一個可以自由拖動的滑塊。 聲明&#xff1a;引用或二創需注明出處。 如圖&#xff1a; 點擊即可直達當前網頁最前、…