泛型设计模式实践

学海无涯,志当存远。燃心砺志,奋进不辍。

愿诸君得此鸡汤,如沐春风,事业有成。

若觉此言甚善,烦请赐赞一枚,共励学途,同铸辉煌!

为解决在设计框架或库时遇到的类型安全问题,或者处理多态集合时的挑战。
希望优化代码结构,减少重复,提高类型安全。
需要结合常见的设计模式,比如工厂模式、策略模式等,展示泛型如何在这些模式中发挥作用。常见的泛型设计模式,比如类型安全的异构容器、泛型单例工厂、策略模式中的泛型应用,以及构建器模式。
需要具体说明每个模式的应用场景、实现方式和优势。
例如,类型安全的异构容器使用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.mzph.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; 点击即可直达当前网页最前、…