1.GoF设计模式总结

1.总结


1.1 基础知识

学习过的24种设计模式

24种设计模式分为三种类型:创建型模式、结构型模式和行为型模式。

  1. 创建型模式:这些模式处理对象创建机制,试图以一种方式来创建对象,以便能够在系统中提供更大的灵活性和可复用性。创建型模式包括:

    • 简单工厂模式(Simple Factory Pattern)
    • 工厂方法模式(Factory Method Pattern)
    • 抽象工厂模式(Abstract Factory Pattern)
    • 单例模式(Singleton Pattern)
    • 原型模式(Prototype Pattern)
    • 建造者模式(Builder Pattern)
  2. 结构型模式:这些模式处理对象组合,试图以一种方式组合类或对象来形成更大的结构。结构型模式包括:

    • 适配器模式(Adapter Pattern)
    • 桥接模式(Bridge Pattern)
    • 组合模式(Composite Pattern)
    • 装饰器模式(Decorator Pattern)
    • 外观模式(Facade Pattern)
    • 享元模式(Flyweight Pattern)
    • 代理模式(Proxy Pattern)
  3. 行为型模式:这些模式处理对象之间的通信,试图以一种更优雅和有效的方式来分配职责。行为型模式包括:

    • 职责链模式(Chain of Responsibility Pattern)
    • 命令模式(Command Pattern)
    • 解释器模式(Interpreter Pattern)
    • 迭代器模式(Iterator Pattern)
    • 中介者模式(Mediator Pattern)
    • 备忘录模式(Memento Pattern)
    • 观察者模式(Observer Pattern)
    • 状态模式(State Pattern)
    • 策略模式(Strategy Pattern)
    • 模板方法模式(Template Method Pattern)
    • 访问者模式(Visitor Pattern)

其他常见的设计模式

  • 依赖注入模式(Dependency Injection Pattern):用于解耦组件之间的依赖关系,通过将依赖关系从代码中移动到配置中或使用特定的框架来实现。
  • 领域驱动设计模式(Domain-driven Design Patterns):这些模式是为了应对复杂业务场景而设计的,例如实体、值对象、聚合根等。
  • 并发模式(Concurrency Patterns):用于处理并发编程中的各种问题,例如锁、信号量、并发数据结构等。
  • 异步模式(Asynchronous Patterns):用于处理异步编程中的任务管理、结果处理等问题,例如回调、Promise、Future等。
  • 消息传递模式(Messaging Patterns):用于构建分布式系统中的消息传递机制,例如消息队列、发布-订阅模式等。

这些模式都是为了解决特定领域中的问题而设计的,使用时需要根据具体场景进行选择和应用。


1.2 面试题精选

基础题

1. GoF 三类模式各自解决什么问题

题目

简述创建型、结构型、行为型三类模式各自关注的矛盾是什么。

深入解析
  • 创建型:对象 如何被创建、谁控制生命周期、怎样在少改调用方的前提下换实现或控制实例个数。
  • 结构型:类或对象 如何拼成更大结构,在少动核心逻辑的前提下做适配、扩展、组合、对外简化接口。
  • 行为型:对象之间 如何协作与分配职责,把算法、请求、状态变化、通知链等从硬编码里拆出去。
答题示例

三类是按问题域划分的。

创建型对应 new 谁、怎么 new、谁来 new;结构型对应 怎么组装 才对外简单、对内可扩展;行为型对应 运行时谁通知谁、谁执行哪段流程,把易变逻辑从硬编码调用里拆出去。

参考文章
  • 1.GoF设计模式概述

2. 单例的饿汉、懒汉、双重检查锁怎么选

题目

各有什么线程安全与资源占用特点,Unity 里 MonoBehaviour 单例还要注意什么?

深入解析
  • 饿汉:静态字段在类型初始化时赋值,CLR 保证初始化线程安全;可能提前占用资源。
  • 懒汉(无锁):首次访问再 new,多线程下可能得到多个实例。
  • 双重检查锁:外层的空判断减少锁竞争,内层在锁内再判空并创建,兼顾懒加载与并发。
  • Unity:生命周期跟场景与 DontDestroyOnLoad 走;Awake 里要做重复实例销毁;查找场景实例的 API 随版本更替,应使用当前文档推荐的查询方式。
答题示例

先确认是否需要懒加载、是否存在多线程竞争。

启动阶段即可创建、希望实现简单:饿汉。延迟创建且有多线程:双重检查锁等线程安全懒式实现。Unity 下 MonoBehaviour 单例不走普通构造,一般在 Awake 判重、Find 或动态建空物体挂脚本 上保证唯一,并结合场景切换考虑是否 DontDestroyOnLoad

参考文章
  • 2.创建型模式-单例模式

3. 外观模式 Facade 解决什么问题

题目

外观是不是「再包一层封装」?和随便写一个工具类聚合调用有什么区别?

深入解析
  • 意图:对一组协作的子系统类型提供稳定、面向用例的入口,降低客户端对子系统拓扑与顺序的感知。
  • 和乱聚合工具类的差别:门面应对应清晰的子系统边界,内部实现可整体替换;若只有静态方法、职责不清,容易变成全项目共用的「杂物间」。
  • 风险:单个 Facade 承接所有入口会膨胀;可按用例或子域拆成多个门面。
答题示例

门面是子系统对外的稳定入口,不是无边界地堆静态工具方法。

它把多步子系统调用收成几条业务流程,调用方只依赖门面。子系统内部重构时,优先在门面内收敛修改面。门面过大就按场景拆分。

参考文章
  • 2.结构型模式-外观模式

4. 观察者模式用接口列表和用 C# 事件各有什么取舍

题目

什么时候用 List<IObserver> 遍历通知,什么时候用 event

深入解析
  • 接口 + 列表:类型明确,可封装注册 / 反注册 / 遍历;适合需要自定义通知语义或与非 .NET 回调风格对齐时。
  • 事件 / 委托:语法简洁,多播内置;要注意 -= 注销、生命周期(Unity 里 OnDestroy 取消订阅)避免悬挂引用。
  • 系列正文也提到:工程里委托实现更常见,但大型框架有时会再包一层主题接口便于测试与扩展。
答题示例

两种做法都能实现一对多通知,选型看团队习惯和框架约束。

列表便于在通知前后插入统一逻辑,测试时也好替换假观察者;event 写法省事,但要保证成对注销。Unity 里组件 OnDestroy 务必取消订阅,避免已销毁对象仍挂在委托上。

参考文章
  • 3.行为型模式-观察者模式

进阶题

1. 「难度 × 频率」排行榜能不能当作学习路线

题目

设计模式学习顺序是否应按网上排行榜来?这类表的价值和局限是什么?

深入解析
  • 价值:给新人一个 机会成本 视角,先掌握高频且曲线不陡的模式,更容易在真实项目里见到正反馈。
  • 局限:难度与频率来自 抽样与作者主观权重,游戏客户端、后端服务、工具链热点并不相同;有些模式全局排名低,却在当前栈里绕不开。
  • 工程说法:排行榜当 选课参考,不当 能力标准;岗位技术栈里反复出现的协作方式,比全局排名第几更该优先吃透。
答题示例

排行表只作参考,不会当作唯一学习顺序。

用它估投入产出:优先啃当前项目里会碰到的。统计口径随领域而变,客户端、后端、工具链热点不一致。结合 耦合点、扩展点、对象生命周期 选型,比背名次有意义。

参考文章
  • 1.GoF设计模式概述

2. 简单工厂和工厂方法差在哪

题目

加一种新产品时,两种写法改动面分别在哪里?

深入解析
  • 简单工厂:创建逻辑集中在一个类的分支里,新产品常要改既有工厂方法,扩展成本落在修改旧代码上。
  • 工厂方法:把「创建」推到具体工厂子类,新产品对应新工厂类 + 新产品类,客户端依赖抽象工厂与抽象产品,旧类可不动。
  • 选型:产品类型少、变化少简单工厂够用;产品族持续膨胀、希望符合开闭原则时用工厂方法。
答题示例

差别在变化点落在谁身上

简单工厂动分支;工厂方法通过新增类型扩展。补充:简单工厂不在 GoF 二十三式正式名单里,工程里仍很常见。

参考文章
  • 3.创建型模式-简单工厂模式
  • 4.创建型模式-工厂方法模式

3. 桥接模式在解决哪种「类爆炸」

题目

两个独立变化维度时,为什么不用多重继承而用桥接?

深入解析
  • 问题形状:形如「平台 × 功能」或「抽象 UI × 皮肤实现」,若用继承枚举所有组合,子类数乘积增长。
  • 桥接做法:抽象侧与实现侧各成独立层次,抽象组合实现接口引用;扩展新平台或新功能主要是加类 + 改组合,不是 N×M 个子类。
  • 原则:合成复用优于为每种组合建子类;与策略思想接近,但桥接强调抽象与实现双维度的长期拆分。
答题示例

两个维度各自会变,用继承会变成笛卡尔积子类。

桥接让抽象侧只依赖实现接口,替换实现即可换平台或换资源形态。手机跑不同系统、英雄换皮肤等都属于这一类拆分。

参考文章
  • 6.结构型模式-桥接模式

4. 状态模式和策略模式看起来都像「换实现」,差别在哪

题目

都是一个上下文里换引用,面试里怎么一句话分开讲?

深入解析
  • 策略:上下文通常不关心当前是哪种策略,调用方或配置注入不同 Strategy 完成同一类任务(如计费规则)。
  • 状态:上下文知道自己处在哪一状态;状态对象里常根据输入迁移到下一状态,行为随状态机而变(如连接态 / 断开态)。
  • 代码气味:若分支主要在描述「对象现在处于生命周期哪一段」,偏状态;若分支只是在选「同一接口下的不同算法」,偏策略。
答题示例

策略侧重同一任务下换算法实现;状态侧重对象在生命周期各阶段行为不同,且常伴随显式迁移。

状态转换多写在状态类或上下文里,形成状态机;策略一般不强调固定的状态迁移图,而是由外部按需注入实现。

参考文章
  • 2.行为型模式-策略模式
  • 7.行为型模式-状态模式

深度题

1. 「基础—标准代码—C#—Unity」四段结构对团队文档的意义

题目

如果团队要求复杂模块按「基础概念、标准结构、C# 示例、Unity 实践」写设计说明,利弊各是什么?

深入解析
  • :促使把 抽象角色、稳定边界、可替换实现 写清楚,新人能按固定套路定位;Unity 一段能把 生命周期、序列化、Inspector 暴露 等引擎侧问题写进设计,而不是停在教科书类图。
  • :小改动也套四段会 文档膨胀;示例与真实架构脱节时,容易变成形式主义。
  • 折中:对 跨模块协议、长期演进的核心系统 用全四段;局部重构用其中一两段即可。
答题示例

四段本质是从抽象到落地的检查清单。

公共模块、多人协作边界上收益大:词汇统一、接口边界清楚。小需求不必四段写满,否则文档比代码还难维护。Unity 一段应写清 生命周期、序列化、场景与预制体关系,与教科书控制台示例区分开。

参考文章
  • 1.GoF设计模式概述

2. 抽象工厂和建造者都在「造一堆东西」,怎么区分

题目

什么需求更该上抽象工厂,什么需求更该上建造者?

深入解析
  • 抽象工厂:强调产品族——一次拿到彼此兼容的一组对象(多接口、多实现,成套切换),扩展新族往往牵动多个产品类与工厂方法。
  • 建造者:强调同一复杂对象的装配过程——Director 管步骤顺序,各 Builder 管每步怎么填;换表示或微调流程时动建造者或 Construct
  • 合一说法:抽象工厂回答「哪一套」;建造者回答「按什么顺序拼出一个」。
答题示例

抽象工厂是成套换皮肤、换配置档;建造者是分步拼一个复杂体

例:换整套 UI 主题像抽象工厂;拼关卡数据、拼角色属性链像建造者。两者都会创建多个对象,但意图不同:一个强调成套族,一个强调装配步骤,记类图时要把这点带上。

参考文章
  • 5.创建型模式-抽象工厂模式
  • 7.创建型模式-建造者模式

3. 享元的内部状态与外部状态,和 ScriptableObject 怎么类比

题目

享元工厂里同一个 key 为什么必须返回同一实例?运行时状态该放哪?

深入解析
  • 内部状态:与 key 绑定、可安全共享、一般不变;工厂字典保证同 key 同对象,才能真省内存。
  • 外部状态:随调用场景变化,通过方法参数传入,不进共享对象的可变字段,否则多使用者互相踩。
  • ScriptableObject:多组件引用同一份资产时,类似共享内部 / 配置数据;若把战斗中的血量、随机种子写进 SO,就变成全局可变单例,和享元初衷相反。
答题示例

享元共享的是不变或极少变的那块;变的都当参数传。

ScriptableObject 适合放共享配置;运行时可变状态应放在实例或组件上,避免写回共享资产。工厂按 key 复用实例,才能保证内存上真的是「一份数据多处引用」。

参考文章
  • 8.结构型模式-享元模式

4. 访问者模式为什么说「对操作扩展开放、对元素类型扩展不友好」

题目

Accept + Visit 双分派解决了什么问题,又带来什么维护成本?

深入解析
  • 稳定元素、多变操作:元素类只实现 Accept,新报表 / 新校验写成新 Visitor,原有 Circle / Rectangle 可少改。
  • 新增元素类型:通常要在 IVisitor 上增加重载,并修改每一个具体访问者实现,否则编译不过——开闭原则向操作侧倾斜。
  • 适用边界:对象结构长期稳定、操作频繁增删(编译器 AST、复杂 UI 树导出)才划算;否则表驱动或 switch 模式匹配可能更简单。
答题示例

双分派把「对某类元素做什么」收敛到 Visitor 的一个重载里,调用关系一目了然。

每新增一种元素类型,往往要改 Visitor 接口及全部实现,改动面大。元素类型仍在快速膨胀时,访问者模式要慎用,可评估表驱动或语言自带的模式匹配等替代方案。

参考文章
  • 11.行为型模式-访问者模式


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏