【面试场景题】如何理解设计模式
文章目录
- 一、设计模式的本质:“解耦”与“复用”
- 二、设计模式的三大分类(23种经典模式)
- 1. 创建型模式(5种):解决“对象创建”的问题
- 2. 结构型模式(7种):解决“类/对象组合”的问题
- 3. 行为型模式(11种):解决“类/对象交互”的问题
- 三、设计模式的价值:“可读性”与“可扩展性”
- 四、常见误区:不要“为了模式而模式”
- 五、总结:设计模式是“前人经验的复用”
设计模式是软件开发中反复出现的问题的通用解决方案,是前辈开发者在长期实践中总结的“最佳实践”。它不是具体的代码,而是解决特定问题的思想、结构和套路,目的是让代码更易维护、更灵活、更复用。
一、设计模式的本质:“解耦”与“复用”
设计模式的核心目标是解决代码中的耦合问题(模块之间依赖过重)和复用问题(重复开发相同功能)。例如:
- 当需要频繁修改“支付方式”(微信、支付宝、银行卡)时,直接硬编码会导致每次新增支付方式都要修改核心代码——这是“耦合过高”。
用策略模式可将支付逻辑与核心流程解耦,新增支付方式只需新增一个类,无需修改原有代码。- 当多个地方需要“记录操作日志”时,复制粘贴日志代码会导致后期修改日志格式时要改所有地方——这是“复用性差”。
用装饰器模式或AOP(面向切面编程,设计模式的衍生)可将日志逻辑抽离,只需定义一次,多处复用。
二、设计模式的三大分类(23种经典模式)
根据解决的问题场景,经典设计模式分为三类:
1. 创建型模式(5种):解决“对象创建”的问题
关注如何灵活地创建对象,而不是硬编码
new
一个对象,避免对象创建逻辑与使用逻辑耦合。
- 单例模式:确保一个类只有一个实例(如配置管理器、线程池)。
- 工厂模式:用工厂类统一创建对象(如
PaymentFactory
根据类型创建微信/支付宝支付对象)。- 建造者模式:复杂对象的分步构建(如
OrderBuilder
分步骤设置订单的商品、地址、支付方式)。
2. 结构型模式(7种):解决“类/对象组合”的问题
关注如何将类或对象组合成更大的结构,同时保持结构的灵活性和可扩展性。
- 适配器模式:让不兼容的接口可以一起工作(如老系统的
Payment
接口与新系统的IPay
接口通过适配器适配)。- 装饰器模式:动态给对象增加功能(如给“基础订单服务”动态添加“日志装饰器”“权限装饰器”)。
- 代理模式:为对象提供代理(如远程代理:通过代理类调用远程服务器的接口,隐藏网络通信细节)。
3. 行为型模式(11种):解决“类/对象交互”的问题
关注类与对象之间的通信方式,确保交互高效且灵活。
- 观察者模式:一个对象变化时通知依赖它的所有对象(如订单状态变更时,自动通知库存系统、物流系统)。
- 策略模式:多种算法/策略可选,运行时动态切换(如根据用户等级选择不同的折扣策略)。
- 迭代器模式:统一遍历集合的方式(如
ArrayList
和LinkedList
用同一套迭代器接口遍历)。
三、设计模式的价值:“可读性”与“可扩展性”
提升代码可读性:
设计模式是开发者的“共同语言”。例如,看到XXXFactory
就知道这是工厂模式,负责创建对象;看到XXXProxy
就知道这是代理模式,负责增强对象功能——无需通读代码即可理解大致逻辑。增强可扩展性:
符合“开闭原则”(对扩展开放,对修改关闭)。例如,用策略模式设计的支付模块,新增“Apple Pay”只需新增一个ApplePayStrategy
类,无需修改原有订单流程代码。减少重复劳动:
避免重复解决相同问题。例如,几乎所有需要“延迟初始化”(第一次使用时才创建对象)的场景,都可以直接套用“懒汉式单例模式”的思路。
四、常见误区:不要“为了模式而模式”
设计模式是工具,不是目的,过度使用会导致代码冗余、复杂度上升:
- 简单场景无需用模式:如一个工具类只需创建一次,直接用
static
方法即可,无需强行实现单例模式。- 理解问题再选模式:先明确要解决的问题(如“需要灵活切换算法”),再选择对应模式(策略模式),而不是先定模式再套问题。
- 模式是“经验总结”而非“银弹”:没有万能模式,实际开发中常需要组合多种模式(如“工厂模式+策略模式”“观察者模式+代理模式”)。
五、总结:设计模式是“前人经验的复用”
设计模式的本质是将“解决特定问题的经验”抽象成通用模板,让开发者站在前辈的肩膀上,少走弯路。
- 对新手:理解模式背后的“设计原则”(如单一职责、依赖倒置)比死记模式代码更重要。
- 对老手:根据业务复杂度灵活选用模式,避免过度设计,记住“简单才是美”。
简单说,设计模式就像“编程字典”——遇到特定问题时,能快速找到经过验证的解决方案,让代码更“专业”。