JAVA重点基础、进阶知识及易错点总结(31)设计模式基础(单例、工厂)

张开发
2026/4/17 8:11:07 15 分钟阅读

分享文章

JAVA重点基础、进阶知识及易错点总结(31)设计模式基础(单例、工厂)
Java 巩固进阶 · 第 31 天主题设计模式基础单例、工厂—— 架构思维的起点 进度概览恭喜完成JDK8 新特性阶段25-30 天从今天起进入设计模式与注解阶段。设计模式是前人总结的套路掌握它能让你写出更优雅、更易维护的代码。 核心价值代码质量遵循设计原则避免面条代码提升可读性与可维护性。面试通关单例模式、工厂模式是初级→中级开发的必考题手写线程安全单例是高频题。框架基石理解 Spring Bean 的单例管理、工厂模式在框架中的广泛应用。设计思维从能跑就行升级到设计优雅培养架构师视角。一、设计模式六大原则先懂原则再学模式 1. 原则速查表⭐ 理解核心思想原则核心思想一句话解释示例单一职责一个类只做一件事“专业的人做专业的事”UserService 只处理用户逻辑不碰订单开闭原则对扩展开放对修改关闭“加功能不改旧代码”用策略模式替代 if-else新增策略不改原逻辑里氏替换子类能替换父类“儿子能替老爸上班”方法参数用父类类型传入子类对象仍正常工作依赖倒置依赖抽象不依赖具体“用接口编程不用实现类”依赖 DataSource 接口而非 MySQLDataSource接口隔离接口要小而专“拒绝胖接口”拆分成 PrintInterface / ScanInterface而非全能 Printer迪米特法则最少知道原则“别管闲事”对象只和直接朋友通信不跨层调用记忆口诀“单开里依接迪” → 单一、开闭、里氏替换、依赖倒置、接口隔离、迪米特二、单例模式确保一个类只有一个实例 1. 为什么需要单例 场景数据库连接池、配置管理器、日志对象 ❌ 问题如果每个地方都 new 一个资源浪费 状态不一致 ✅ 解决单例模式全局唯一实例节约资源 统一状态2. 四种实现方式对比⭐ 必背// ✅ 方式 1饿汉式类加载时创建线程安全publicclassSingleton{privatestaticfinalSingletoninstancenewSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returninstance;}}// 优点简单线程安全// 缺点类加载就创建可能浪费资源如果不用// ✅ 方式 2懒汉式首次使用时创建需同步publicclassSingleton{privatestaticSingletoninstance;privateSingleton(){}publicstaticsynchronizedSingletongetInstance(){if(instancenull){instancenewSingleton();}returninstance;}}// 优点延迟加载// 缺点每次调用都同步性能差// ✅✅ 方式 3双重检查锁DCL⭐ 推荐publicclassSingleton{// ⚠️ volatile 关键防止指令重排序导致返回未初始化对象privatestaticvolatileSingletoninstance;privateSingleton(){}publicstaticSingletongetInstance(){if(instancenull){// 第一次检查synchronized(Singleton.class){if(instancenull){// 第二次检查instancenewSingleton();// 非原子操作分配内存→初始化→返回引用}}}returninstance;}}// 优点延迟加载 线程安全 高性能只同步一次// 关键volatile 禁止重排序确保其他线程拿到完全初始化的对象// ✅✅ 方式 4枚举单例⭐ 最安全推荐publicenumSingleton{INSTANCE;publicvoiddoSomething(){/* 业务方法 */}}// 优点// 1. 天然线程安全JVM 保证// 2. 防止反射破坏构造器会被反射调用枚举不会// 3. 防止序列化破坏readResolve 自动处理// 缺点不支持延迟加载但大部分场景不需要3. ⚠️ 单例的破坏与防御// 破坏 1反射调用私有构造器ConstructorSingletonconsSingleton.class.getDeclaredConstructor();cons.setAccessible(true);Singletons2cons.newInstance();// ❌ 创建了第二个实例// ✅ 防御枚举单例 / 构造器内判断privateSingleton(){if(instance!null){thrownewRuntimeException(禁止反射创建单例);}}// 破坏 2序列化反序列化// 反序列化会创建新对象绕过构造器// ✅ 防御实现 readResolve() 方法privateObjectreadResolve(){returninstance;// 返回已有实例}生产建议简单场景 → 饿汉式代码简洁延迟加载 → 双重检查锁记得 volatile最安全 → 枚举单例Effective Java 推荐三、工厂模式解耦对象创建 1. 简单工厂静态工厂方法// ✅ 场景根据参数创建不同对象调用方无需知道具体类publicclassAnimalFactory{publicstaticAnimalcreateAnimal(Stringtype){switch(type.toLowerCase()){casecat:returnnewCat();casedog:returnnewDog();default:thrownewIllegalArgumentException(未知类型);}}}// 调用Animala1AnimalFactory.createAnimal(cat);// 解耦调用方不 new Cat()⚠️缺点违反开闭原则新增动物类型需修改工厂类2. 工厂方法模式⭐ 符合开闭原则// 1. 抽象工厂接口publicinterfaceAnimalFactory{AnimalcreateAnimal();}// 2. 具体工厂publicclassCatFactoryimplementsAnimalFactory{publicAnimalcreateAnimal(){returnnewCat();}}publicclassDogFactoryimplementsAnimalFactory{publicAnimalcreateAnimal(){returnnewDog();}}// 3. 调用AnimalFactoryfactorynewCatFactory();Animalafactory.createAnimal();// 新增动物只需加新工厂不改旧代码 ✅3. 工厂模式对比表模式核心思想优点缺点适用场景简单工厂一个工厂类创建所有对象调用方解耦代码集中违反开闭原则对象类型少不频繁扩展工厂方法每个对象对应一个工厂子类符合开闭原则易扩展类数量增多对象类型多需频繁扩展抽象工厂工厂创建产品族进阶支持产品族扩展结构复杂相关产品需一起创建如 UI 主题Spring 实践BeanFactory/ApplicationContext是工厂模式的极致应用Autowired注入的 Bean底层由 Spring 工厂创建 管理四、 今日实战任务模式实战演练任务 1实现线程安全单例双重检查锁/** * 要求 * 1. 用双重检查锁实现 ConfigManager 单例 * 2. 添加 volatile 关键字理解其作用 * 3. 编写多线程测试验证是否只创建一个实例 * * 调试技巧 * - 在构造器中打印 Created: System.identityHashCode(this) * - 多线程调用 getInstance()观察 hashCode 是否相同 */任务 2用工厂方法创建交通工具/** * 业务场景出行服务支持汽车/自行车/飞机 * * 要求 * 1. 定义抽象类 Vehicle抽象方法 start() * 2. 创建 Car/Bike/Plane 子类实现 start() * 3. 定义 VehicleFactory 接口 具体工厂类 * 4. 调用方通过工厂创建对象调用 start() * * 挑战 * - 如果新增高铁类型需要修改哪些代码验证开闭原则 */任务 3单例 工厂组合实战/** * 业务场景数据库连接管理器单例 连接工厂 * * 要求 * 1. ConnectionManager 用枚举单例实现 * 2. 内部用工厂方法创建 MySQL/PostgreSQL 连接 * 3. 提供 getConnection(String type) 方法 * * 思考 * - 为什么连接管理器用单例全局唯一管理连接池 * - 为什么连接创建用工厂解耦具体数据库驱动 */任务 4对比实验单例性能测试/** * 要求 * 1. 分别实现饿汉式、懒汉式、双重检查锁、枚举单例 * 2. 用 100 线程并发调用 10000 次 getInstance() * 3. 统计每种方案的耗时 实例数量验证是否单例 * * 预期结论 * - 饿汉式最快无同步开销 * - 懒汉式synchronized最慢每次同步 * - 双重检查锁接近饿汉式只同步一次 * - 枚举与饿汉式相当JVM 保证 */ 第 31 天 · 核心总结极简背诵版六大原则速记单开里依接迪 单一职责 / 开闭 / 里氏替换 / 依赖倒置 / 接口隔离 / 迪米特单例模式四实现饿汉式类加载创建简单安全 懒汉式延迟加载需同步 双重检查锁⭐ 延迟安全高性能记得volatile 枚举单例⭐ 最安全防反射/序列化破坏工厂模式对比简单工厂一个工厂类违反开闭 工厂方法每个产品一个工厂符合开闭推荐 抽象工厂创建产品族进阶生产建议✅ 单例优先用枚举其次双重检查锁✅ 工厂模式优先工厂方法便于扩展❌ 避免滥用单例全局状态难测试明天预告️设计模式建造者、原型—— 复杂对象创建方案建造者模式链式调用构建复杂对象如 UserBuilder原型模式克隆对象浅克隆 vs 深克隆实战用建造者模式创建电脑配置用原型模式实现简历克隆准备好了吗明天我们攻克对象创建的另外两种套路 ✨

更多文章