设计模式是软件开发中解决特定问题的可复用方案,是优秀工程师的必备知识库。掌握它们不仅能提升代码质量与可维护性,也是技术面试中的高频考点。本文梳理常见设计模式,并解析其核心思想与应用场景,供学习研究与面试准备。
一、创建型模式:专注于对象的创建机制
- 单例模式 (Singleton)
- 核心思想:确保一个类只有一个实例,并提供全局访问点。
- 典型应用:数据库连接池、日志对象、配置管理器等需要全局唯一资源的场景。
- 面试要点:懒汉式与饿汉式的区别、线程安全的实现方式(如双重检查锁定)、静态内部类实现。
- 工厂方法模式 (Factory Method)
- 核心思想:定义一个创建对象的接口,但由子类决定实例化哪个类。将对象的创建延迟到子类。
- 典型应用:日志记录器(可输出到文件、数据库或控制台)、连接器工厂。
- 面试要点:与简单工厂的区别,符合“开闭原则”(对扩展开放,对修改封闭)。
- 抽象工厂模式 (Abstract Factory)
- 核心思想:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
- 典型应用:GUI 库(为不同操作系统创建一套控件族,如按钮、文本框)。
- 面试要点:强调“产品族”概念,与工厂方法模式(关注单一产品等级)的区别。
- 建造者模式 (Builder)
- 核心思想:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
- 典型应用:构造复杂对象(如包含多种可选部件的计算机、包含多种信息的订单)。
- 面试要点:适用于构造过程稳定但配置灵活的对象,与工厂模式(关注产品类型)的区别。
二、结构型模式:处理类或对象的组合
- 适配器模式 (Adapter)
- 核心思想:将一个类的接口转换成客户期望的另一个接口,使不兼容的类能协同工作。
- 面试要点:类适配器(通过继承)与对象适配器(通过组合)的实现与优劣。
- 装饰器模式 (Decorator)
- 核心思想:动态地给一个对象添加一些额外的职责,相比生成子类更为灵活。
- 典型应用:Java I/O 流(如 BufferedReader 包装 FileReader)、为组件动态添加功能(如滚动条)。
- 面试要点:强调“透明装饰”与继承的区别,符合“组合优于继承”原则。
- 代理模式 (Proxy)
- 核心思想:为其他对象提供一种代理以控制对这个对象的访问。
- 典型应用:远程代理(RPC)、虚拟代理(延迟加载大对象)、保护代理(权限控制)。
- 面试要点:与装饰器模式(增强功能)的区别在于,代理主要控制访问。
- 外观模式 (Facade)
- 核心思想:为子系统中的一组接口提供一个一致的简化接口,降低子系统与客户端之间的耦合。
- 典型应用:框架封装底层复杂 API、提供简化的 SDK。
- 面试要点:强调简化接口,而非添加新功能,是架构层次的常用模式。
三、行为型模式:处理对象间的职责分配与通信
- 观察者模式 (Observer)
- 核心思想:定义对象间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。
- 典型应用:事件监听系统、消息队列、MVC 框架中的模型与视图关系。
- 面试要点:推模型与拉模型的区别,在现代框架中的体现(如 ReactiveX)。
- 策略模式 (Strategy)
- 核心思想:定义一系列算法,将它们封装起来,并且使它们可以相互替换,让算法独立于使用它的客户端而变化。
- 典型应用:排序算法(客户可选择不同策略)、支付方式(支付宝、微信、银行卡)。
- 面试要点:消除条件判断语句,符合“多用组合,少用继承”原则。
- 模板方法模式 (Template Method)
- 核心思想:定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变算法结构即可重定义某些步骤。
- 典型应用:框架的钩子方法(如 Spring 的 JdbcTemplate)、工作流定义。
- 面试要点:强调对算法流程的控制,是代码复用的基础技术。
四、学习研究与面试实践建议
- 理解比记忆更重要:不要死记硬背 UML 图,重点理解每种模式要解决的痛点、适用场景及优缺点。
- 联系实际项目:尝试在阅读开源代码或回顾自身项目时,识别已使用的模式,并思考其设计意图。
- 准备面试阐述:对于常见模式(如单例、工厂、观察者、装饰器),能清晰口述其定义、UML 关键角色、代码示例及一个具体的应用场景。
- 辨析相似模式:面试中常要求比较相似模式,如工厂方法与抽象工厂、策略与状态、装饰器与代理等。
- 避免过度设计:在面试中讨论设计模式时,需同时指出其可能带来的复杂性,强调模式是工具,应在必要时使用。
设计模式是前人经验的结晶,其精髓在于理解“封装变化”、“松耦合”等设计原则。持续在实践中思考与运用,方能内化为真正的工程能力,在系统设计与技术面试中游刃有余。