Java设计模式23种实战详解:从理论到落地,附完整可运行代码

📅 2026/7/6 7:14:34
Java设计模式23种实战详解:从理论到落地,附完整可运行代码
引言设计模式是软件工程中经过反复验证的解决方案是开发高质量代码的基石。GoFGang of Four提出的23种经典设计模式至今仍是Java开发者的必备技能。然而许多同学在学习时往往只停留在“看懂”层面遇到实际项目或面试手写时便手足无措。本文将带你通过完整可运行的代码深入掌握最常用的几种设计模式并梳理所有23种模式的核心要点助你从理论到实战一步到位。核心概念23种设计模式一览根据目的和范围设计模式可分为三大类创建型模式5种单例、工厂方法、抽象工厂、建造者、原型结构型模式7种适配器、桥接、组合、装饰、外观、享元、代理行为型模式11种责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者每个模式都有其适用场景和设计原则开闭原则、里氏替换、依赖倒置等。下面我们将聚焦面试最高频、项目最常用的7种模式提供可直接运行的示例代码其余模式则以表格形式给出速查。实战示例7大高频模式完整代码1. 单例模式Singleton——保证全局唯一实例场景数据库连接池、配置管理器。实现双重检查锁定DCL volatile兼顾性能与线程安全。public class Singleton { // volatile防止指令重排确保其他线程看到的是初始化完成的实例 private static volatile Singleton instance; private Singleton() { // 私有构造防止外部new } public static Singleton getInstance() { if (instance null) { // 第一次检查避免不必要的同步 synchronized (Singleton.class) { if (instance null) { // 第二次检查确保单例 instance new Singleton(); } } } return instance; } public void doSomething() { System.out.println(单例模式工作…); } public static void main(String[] args) { Singleton s1 Singleton.getInstance(); Singleton s2 Singleton.getInstance(); System.out.println(s1 s2); // true } }2. 工厂方法模式Factory Method——将对象的创建延迟到子类场景日志记录器根据配置选择文件日志或数据库日志。代码定义一个日志工厂接口由具体工厂决定实现类。// 产品接口 interface Logger { void log(String msg); } // 具体产品 class FileLogger implements Logger { public void log(String msg) { System.out.println(写入文件日志: msg); } } class DBLogger implements Logger { public void log(String msg) { System.out.println(写入数据库日志: msg); } } // 工厂接口 abstract class LoggerFactory { public abstract Logger createLogger(); // 公共逻辑可以放在这里 public void writeLog(String msg) { Logger logger createLogger(); logger.log(msg); } } // 具体工厂 class FileLoggerFactory extends LoggerFactory { public Logger createLogger() { return new FileLogger(); } } class DBLoggerFactory extends LoggerFactory { public Logger createLogger() { return new DBLogger(); } } // 测试 public class FactoryMethodTest { public static void main(String[] args) { LoggerFactory factory new FileLoggerFactory(); factory.writeLog(用户登录); factory new DBLoggerFactory(); factory.writeLog(订单支付); } }3. 抽象工厂模式Abstract Factory——创建一组相关或依赖的对象场景跨平台的UI组件如Windows风格和Mac风格的按钮、文本框。代码以下展示一个简单版创建同一家族的武器与防具。// 抽象产品 interface Weapon { void use(); } interface Armor { void protect(); } // 具体产品现代风格 class Gun implements Weapon { public void use() { System.out.println(使用现代武器步枪); } } class Kevlar implements Armor { public void protect() { System.out.println(穿上现代防具凯夫拉); } } // 具体产品魔法风格 class Wand implements Weapon { public void use() { System.out.println(使用魔法武器魔杖); } } class Robe implements Armor { public void protect() { System.out.println(穿上魔法防具法袍); } } // 抽象工厂 interface EquipmentFactory { Weapon createWeapon(); Armor createArmor(); } // 具体工厂 class ModernFactory implements EquipmentFactory { public Weapon createWeapon() { return new Gun(); } public Armor createArmor() { return new Kevlar(); } } class MagicFactory implements EquipmentFactory { public Weapon createWeapon() { return new Wand(); } public Armor createArmor() { return new Robe(); } } // 测试 public class AbsFactoryTest { public static void main(String[] args) { EquipmentFactory factory new ModernFactory(); Weapon w factory.createWeapon(); Armor a factory.createArmor(); w.use(); a.protect(); factory new MagicFactory(); w factory.createWeapon(); a factory.createArmor(); w.use(); a.protect(); } }4. 观察者模式Observer——一对多依赖一个对象变化自动通知其他对象场景订阅-发布系统股票价格变动通知所有观察者。Java内置支持java.util.Observer已过时推荐自定义实现。import java.util.ArrayList; import java.util.List; // 主题接口 interface Subject { void attach(Observer o); void detach(Observer o); void notifyObservers(); } // 具体主题股票价格 class StockPrice implements Subject { private ListObserver observers new ArrayList(); private double price; public void setPrice(double price) { this.price price; notifyObservers(); } public double getPrice() { return price; } public void attach(Observer o) { observers.add(o); } public void detach(Observer o) { observers.remove(o); } public void notifyObservers() { for (Observer o : observers) o.update(this); } } // 观察者接口 interface Observer { void update(Subject subject); } // 具体观察者显示板 class PriceDisplay implements Observer { private String name; public PriceDisplay(String name) { this.name name; } public void update(Subject subject) { if (subject instanceof StockPrice) { StockPrice sp (StockPrice) subject; System.out.println(name 收到价格更新: sp.getPrice()); } } } // 测试 public class ObserverTest { public static void main(String[] args) { StockPrice stock new StockPrice(); stock.attach(new PriceDisplay(显示器A)); stock.attach(new PriceDisplay(显示器B)); stock.setPrice(100.5); stock.setPrice(105.2); } }5. 策略模式Strategy——封装算法族可互相替换场景支付方式、排序算法选择。代码购物车根据会员等级采用不同的折扣算法。// 策略接口 interface DiscountStrategy { double discount(double price); } // 具体策略 class NoDiscount implements DiscountStrategy { public double discount(double price) { return price; } } class VipDiscount implements DiscountStrategy { public double discount(double price) { return price * 0.8; } } class SuperVipDiscount implements DiscountStrategy { public double discount(double price) { return price * 0.6; } } // 环境类 class ShoppingCart { private DiscountStrategy strategy; public void setStrategy(DiscountStrategy strategy) { this.strategy strategy; } public double calculate(double price) { return strategy.discount(price); } } // 测试 public class StrategyTest { public static void main(String[] args) { ShoppingCart cart new ShoppingCart(); double price 200.0; cart.setStrategy(new NoDiscount()); System.out.println(普通会员价格: cart.calculate(price)); cart.setStrategy(new VipDiscount()); System.out.println(VIP价格: cart.calculate(price)); cart.setStrategy(new SuperVipDiscount()); System.out.println(超级VIP价格: cart.calculate(price)); } }6. 装饰器模式Decorator——动态给对象添加额外职责场景Java I/O流BufferedReader装饰Reader。代码一个简单的咖啡配料装饰。// 抽象组件 interface Coffee { double cost(); String desc(); } // 具体组件 class SimpleCoffee implements Coffee { public double cost() { return 10; } public String desc() { return 基础咖啡; } } // 抽象装饰器 abstract class CoffeeDecorator implements Coffee { protected Coffee decoratedCoffee; public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee coffee; } public double cost() { return decoratedCoffee.cost(); } public String desc() { return decoratedCoffee.desc(); } } // 具体装饰器 class Milk extends CoffeeDecorator { public Milk(Coffee coffee) { super(coffee); } public double cost() { return super.cost() 2; } public String desc() { return super.desc() 牛奶; } } class Sugar extends CoffeeDecorator { public Sugar(Coffee coffee) { super(coffee); } public double cost() { return super.cost() 1; } public String desc() { return super.desc() 糖; } } // 测试 public class DecoratorTest { public static void main(String[] args) { Coffee coffee new SimpleCoffee(); System.out.println(coffee.desc() 价格: coffee.cost()); coffee new Milk(coffee); System.out.println(coffee.desc() 价格: coffee.cost()); coffee new Sugar(coffee); System.out.println(coffee.desc() 价格: coffee.cost()); } }7. 代理模式Proxy——控制对对象的访问场景远程代理、虚拟代理、保护代理。如Spring AOP。代码静态代理示例实现一个图片加载的虚拟代理。// 公共接口 interface Image { void display(); } // 真实对象 class RealImage implements Image { private String filename; public RealImage(String filename) { this.filename filename; loadFromDisk(); } private void loadFromDisk() { System.out.println(从磁盘加载图片: filename); } public void display() { System.out.println(显示图片: filename); } } // 代理类 class ProxyImage implements Image { private RealImage realImage; private String filename; public ProxyImage(String filename) { this.filename filename; } public void display() { if (realImage null) { realImage new RealImage(filename); // 延迟加载 } realImage.display(); } } // 测试 public class ProxyTest { public static void main(String[] args) { Image image new ProxyImage(test.jpg); System.out.println(图片对象已创建但未加载); image.display(); // 首次调用才加载 image.display(); // 直接显示不再加载 } }其余16种模式速查表篇幅所限不能全部展开。下表整理了剩余模式的核心意图与关键结构方便你快速回忆。模式名称类型意图核心代码结构建造者创建型分步骤构建复杂对象Product.Builder().setA().setB().build()原型创建型通过克隆创建对象实现Cloneable重写clone()适配器结构型转换接口兼容不匹配的类适配器类持有被适配对象实现目标接口桥接结构型分离抽象与实现使其独立变化抽象类持有实现类引用组合结构型用树形结构表示部分-整体Component抽象类叶子与复合节点外观结构型为子系统提供统一入口外观类封装多个内部类调用享元结构型共享细粒度对象减少内存工厂维护已创建对象池内部状态与外部状态分离责任链行为型多个处理者传递请求每个处理器持有下一个引用直到处理命令行为型将请求封装为对象支持撤销命令接口execute接收者调用者解释器行为型解释自定义语言文法抽象表达式终结符与非终结符实现迭代器行为型顺序访问集合元素而不暴露内部结构JavaIterator接口中介者行为型用中介对象封装交互减少直接耦合中介对象维护同事引用备忘录行为型保存对象状态以便恢复原发器创建备忘录管理者保存状态行为型对象行为随内部状态改变状态接口具体状态实现上下文持有当前状态模板方法行为型父类定义算法骨架子类实现具体步骤抽象类中声明模板方法步骤方法为抽象访问者行为型在不改变元素类的情况下新增操作Visitor接口元素accept(Visitor)常见问题与注意事项单例模式在反射和序列化下可能被破坏解决办法在构造器中判断实例是否已存在抛出异常实现readResolve()方法返回实例。避免滥用设计模式设计模式是解药不是补药。如果场景简单过度设计会让代码难以维护。区分工厂方法与抽象工厂工厂方法关注的是单个产品的创建抽象工厂关注的是一族相关产品的创建。观察者模式的内存泄漏风险务必在不需要时移除观察者否则主题持有观察者引用会导致无法GC。装饰器与代理的区别装饰器主要增强功能客户端通常自己组合装饰代理主要控制访问代理对象通常由程序生成如动态代理。动态代理与静态代理Java的java.lang.reflect.Proxy可以在运行时动态创建代理类省略大量重复的静态代理类编写是AOP的基础。总结本文通过7个高频设计模式的完整可运行代码带你跨越“看懂”到“会用”的鸿沟并全面梳理了23种模式的核心概念。设计模式的学习应当遵循理解意图 → 记清类图 → 手写代码 → 结合框架Spring/MyBatis加深理解。希望这篇文章能成为你备战面试和日常开发的案头参考。代码可以在本地直接复制运行快速验证想法。接下来你可以尝试将某些模式组合使用比如策略工厂、观察者代理真正领悟设计模式带来的灵活与优雅。