08. 面向对象技术¶
面向对象基础、开发过程与设计原则、UML 和设计模式。
配套阅读:面向对象技术:课件笔记,含课程配图、例题和参考解析。
配套阅读:【软件设计】UML建模(案例题):课件笔记,含课程配图、例题和参考解析。
配套阅读:【软件设计】面向对象程序设计:课件笔记,含课程配图、例题和参考解析。
本章目录¶
面向对象基础与设计原则¶
专题讲解:面向对象基础与开发流程,包含对象与类、多态分类、OOA 活动、类与组件设计原则,以及 12 张本地配图和 10 道例题解析。
---
markmap:
height: 760
initialExpandLevel: 2
autoFit: true
colorFreezeLevel: 2
maxWidth: 280
spacingHorizontal: 80
spacingVertical: 12
nodeMinHeight: 24
paddingX: 10
---
# 对象、类与多态
## 对象与类
- 对象具有标识、状态和行为
- 类描述一组对象共同的结构与行为
- 封装
- 把状态和操作组织在一起,通过接口隐藏实现细节
- 接口
- 描述可提供的操作与契约,使使用者不依赖具体实现
- 接口不是普遍意义上的特殊类
- 是否允许默认方法等实现,取决于具体语言
- 消息
- 对象之间请求某项行为,如方法调用或异步消息
- 对象交互不必经过网络通信
## 继承、重写与重载
- 继承
- 子类继承并扩展父类允许继承的成员与行为
- 形成一般与特殊的关系,不等于多个实例共享同一份状态
- 重写 Override
- 子类为继承的可重写方法提供符合契约的新实现
- 重载 Overload
- 同名操作具有不同参数列表,由语言规则选择候选
- 仅改变返回类型通常不足以构成重载
- 绑定
- 静态绑定:编译阶段确定调用目标
- 动态绑定:运行时根据对象实际类型等信息选择实现
## 多态的分类
- 通用多态
- 参数多态:泛型参数使同一算法适用于多种类型
- 包含/子类型多态:通过父类型或接口使用不同实现
- 特定多态
- 重载多态:同一名字对应不同类型的操作
- 强制转换多态:通过类型转换使操作适用
- 运行时多态常通过动态分派实现
- 多态并不全部依赖运行时绑定
- 重载、泛型和转换的具体行为由语言类型系统决定
---
markmap:
height: 760
initialExpandLevel: 2
autoFit: true
colorFreezeLevel: 2
maxWidth: 280
spacingHorizontal: 80
spacingVertical: 12
nodeMinHeight: 24
paddingX: 10
---
# 面向对象开发与设计原则
## 开发活动
- 面向对象分析 OOA
- 识别领域对象、职责、关系和业务规则
- 组织对象,描述对象间交互及可执行的操作
- 面向对象设计 OOD
- 将领域模型细化为类、接口、协作、持久化与技术架构
- 面向对象编程 OOP
- 结合语言的类型、封装、继承与组合机制实现设计
- 面向对象测试
- 算法层:方法内部逻辑、边界与异常
- 类层:状态不变量、方法序列、继承与多态
- 协作/类簇层:类之间的接口和交互
- 系统层:端到端行为与质量需求
## SOLID
- 单一职责 SRP
- 一个模块围绕同一类职责组织,避免多个独立变化原因
- 开闭原则 OCP
- 对预期变化保留扩展点,减少对稳定代码的修改
- 里氏替换 LSP
- 子类型可替代父类型,并保持调用者依赖的行为契约
- 不加强前置条件,不削弱后置条件,保持不变量
- 依赖倒置 DIP
- 高层策略与底层细节依赖抽象,细节实现抽象
- 依赖注入是实现手段之一,不等同于原则本身
- 接口隔离 ISP
- 客户端只依赖需要的操作,按使用方职责拆分接口
## 协作与复用
- 组合复用
- 用对象组合与委托复用行为,降低对继承层次的耦合
- 继承适用于满足替换契约的一般与特殊关系
- 迪米特法则/最少知识
- 尽量只与直接协作者交互,减少跨越多层对象的依赖
## 包与组件原则
- 共同复用原则 CRP
- 将通常一起被复用的类放在同一组件
- 避免使用少量功能却依赖大量无关内容
- 共同封闭原则 CCP
- 将因相同原因、同时变化的类放在一起
- 使同类变更尽量集中于少量组件
- 不要求一次变更必然修改包内所有类
## 建模与模式
- [UML](/software-design/08-object-oriented/#uml)
- [设计模式](/software-design/08-object-oriented/#design-patterns)
UML¶
专题讲解:UML 图、关系与读图练习,包含图的分类、关系箭头、多重性、33 张本地配图与 8 道例题解析。
专题讲解:UML 活动图与软件设计师考点,包含读图步骤、节点区别、补图示例和自编练习。
专题讲解:UML 状态图与软件设计师考点,通过订单生命周期理解事件、守卫、转换效果、自转换与复合状态。
---
markmap:
height: 760
initialExpandLevel: 2
autoFit: true
colorFreezeLevel: 2
maxWidth: 280
spacingHorizontal: 80
spacingVertical: 12
nodeMinHeight: 24
paddingX: 10
---
# UML 图的分类
## 统一建模语言
- 用约定的模型元素与符号描述系统
- 可用于需求、分析、设计和沟通,不规定必须采用的开发过程
- UML 2.x 常分为 7 种结构图与 7 种行为图
- 交互图是行为图的子类
## 结构图
- 类图
- 描述类、接口、属性、操作及其静态关系
- 可见性:`+` 公有、`-` 私有、`#` 保护、`~` 包可见
- 对象图
- 描述特定时刻的实例、属性值及对象间的链接
- 构件图/组件图
- 描述组件、提供和需要的接口,以及依赖
- 部署图
- 描述设备、执行环境和制品的部署关系
- 包图
- 组织模型元素,描述包间依赖
- 组合结构图
- 描述分类器内部的部件、端口和连接器
- 轮廓图 Profile
- 通过构造型等扩展机制为特定领域定制 UML
## 行为图
- 用例图
- 描述参与者、系统边界、用例及其关系
- 参与者是外部角色,可以是人或其他系统
- 活动图
- 描述工作流、控制流与对象流
- 分支/合并表达选择,分叉/汇合表达并发与同步
- 状态机图
- 描述状态、事件、转换和动作
- 转换可附带触发事件、守卫条件与执行效果
## 交互图
- 顺序图/序列图
- 沿生命线描述消息的先后关系
- 可表达同步、异步、返回和条件/循环片段
- 通信图
- 强调参与交互的对象连接,通过消息编号表示顺序
- 交互概览图
- 用活动式流程组织多个交互片段
- 时间图/定时图
- 沿时间轴展示状态或数值变化与时间约束
---
markmap:
height: 760
initialExpandLevel: 2
autoFit: true
colorFreezeLevel: 2
maxWidth: 280
spacingHorizontal: 80
spacingVertical: 12
nodeMinHeight: 24
paddingX: 10
---
# UML 关系
## 关联与多重性
- 关联 Association
- 描述实例之间可存在的结构性连接,常用实线
- 可标注角色、导航方向和多重性
- 多重性
- `1`:恰好一个;`0..1`:零个或一个
- `*`/`0..*`:零个或多个;`1..*`:一个或多个
- 一端的数值描述对端一个实例可关联到本端的实例数量
- 聚合 Aggregation
- 整体与部分关系,空心菱形位于整体端
- 表示较弱的整体关系,不强制部分随整体销毁
- 组合 Composition
- 强所有权关系,实心菱形位于整体端
- 部分在同一时刻至多归属于一个组合整体
- 整体销毁时,其仍被拥有的部分也随之销毁
- 不要求整体与部分一定同时创建;部分可在销毁前移出
## 类型与依赖
- 泛化 Generalization
- 特殊类型继承一般类型,实线空心三角指向父类型
- 实现 Realization
- 实现者履行规范或接口契约,虚线空心三角指向规范
- 类实现接口是常见形式
- 依赖 Dependency
- 一方使用另一方,后者变化可能影响前者
- 虚线箭头从使用方指向被依赖方
- 参数、局部变量、调用等可产生依赖
## 用例关系
- 参与者与用例的关联
- 实线表示交互参与,不表达执行的时间顺序
- 包含 include
- 基础用例在指定位置纳入另一个用例的行为
- 用于抽取公共且必要的行为
- 虚线箭头从包含者指向被包含用例,标注 `«include»`
- 扩展 extend
- 在扩展点满足条件时,为基础用例加入额外行为
- 基础用例本身应具有独立完整的含义
- 虚线箭头从扩展用例指向基础用例,标注 `«extend»`
- 泛化
- 特化用例或参与者继承一般者的特征并可加以扩展
- 实线空心三角从特化者指向一般者
设计模式¶
专题讲解:设计模式分类、类图与考题解析,包含 23 种模式的分类、关键词与角色、31 张本地配图和三道综合例题解析。
---
markmap:
height: 760
initialExpandLevel: 2
autoFit: true
colorFreezeLevel: 2
maxWidth: 280
spacingHorizontal: 80
spacingVertical: 12
nodeMinHeight: 24
paddingX: 10
---
# 创建型模式:对象如何产生
## 分类维度
- 目的:创建型、结构型、行为型
- 类模式以继承关系为主,对象模式以对象组合与协作为主
- 经典模式共 23 种,其中创建型 5 种
## 工厂方法 Factory Method
- 类模式:定义创建接口,由子类决定实例化哪种产品
- 将产品使用逻辑与具体产品的创建分离
## 抽象工厂 Abstract Factory
- 对象模式:提供创建一族相关或兼容对象的接口
- 切换工厂可切换产品族;增加新产品种类会影响工厂接口
## 建造者 Builder
- 对象模式:把复杂对象的构建过程与最终表示分离
- 分步组装,同一构建流程可形成不同表示
## 原型 Prototype
- 对象模式:复制已有原型实例创建新对象
- 复制语义需区分浅拷贝、深拷贝与资源共享
## 单例 Singleton
- 对象模式:在指定作用域内控制唯一实例,并提供访问点
- 唯一性取决于进程、类加载器等边界,不自动保证跨进程唯一
- 并发初始化、全局状态与生命周期属于实现约束
---
markmap:
height: 760
initialExpandLevel: 2
autoFit: true
colorFreezeLevel: 2
maxWidth: 280
spacingHorizontal: 80
spacingVertical: 12
nodeMinHeight: 24
paddingX: 10
---
# 结构型模式:对象如何组合
## 适配器 Adapter
- 类模式或对象模式:把已有接口转换为客户端期望的接口
- 类适配器使用继承;对象适配器通过包装与委托适配
## 桥接 Bridge
- 对象模式:将抽象部分与实现部分分离,使二者可独立变化
- 用组合连接两个变化维度,避免继承层次交叉膨胀
## 组合 Composite
- 对象模式:将对象组织为表示整体与部分关系的树
- 统一处理叶节点和组合节点,如文件与目录
## 装饰 Decorator
- 对象模式:通过包装动态叠加职责,保持共同接口
- 包装可嵌套,具体附加行为由装饰对象实现
## 外观 Facade
- 对象模式:为复杂子系统提供统一、较高层的入口
- 简化常见调用,不要求禁止访问子系统底层接口
## 享元 Flyweight
- 对象模式:共享大量细粒度对象中可复用的内部状态
- 外部状态由调用方传入,以减少重复存储
## 代理 Proxy
- 对象模式:以替身控制对真实对象的访问
- 可用于远程访问、延迟加载、权限检查或缓存
---
markmap:
height: 760
initialExpandLevel: 2
autoFit: true
colorFreezeLevel: 2
maxWidth: 280
spacingHorizontal: 80
spacingVertical: 12
nodeMinHeight: 24
paddingX: 10
---
# 行为型模式:职责与交互如何组织
## 职责链 Chain of Responsibility
- 对象模式:让多个处理者依次获得处理请求的机会
- 发送者与具体接收者解耦,请求沿链传递
## 命令 Command
- 对象模式:将请求封装成对象,分离调用者与接收者
- 可支持排队、记录、撤销;撤销需额外设计逆操作或状态保存
## 解释器 Interpreter
- 类模式:为一种语言的语法规则建立表示,并解释其句子
- 常用于规则表达式或简单领域语言,不等同于所有虚拟机实现
## 迭代器 Iterator
- 对象模式:顺序访问聚合对象的元素而不暴露内部表示
- 将遍历状态和遍历算法从容器中分离
## 中介者 Mediator
- 对象模式:用中介对象封装一组对象之间的交互规则
- 减少对象彼此直接依赖,协调逻辑集中于中介
## 备忘录 Memento
- 对象模式:在不破坏封装的前提下保存并恢复对象状态
- 由发起者创建和恢复快照,管理者保存快照
## 观察者 Observer
- 对象模式:建立一对多依赖,主题变化时通知观察者
- 通知与更新可同步或异步,需明确订阅和解除订阅的生命周期
## 状态 State
- 对象模式:封装各状态的行为,让对象随内部状态改变表现
- 状态转换可由上下文或状态对象负责
## 策略 Strategy
- 对象模式:封装可互换算法,通过统一接口替换算法
- 由上下文组合策略,算法变化不要求修改调用者
## 模板方法 Template Method
- 类模式:在父类定义算法骨架,由子类实现或覆盖部分步骤
- 保持总体步骤顺序,使用抽象操作和钩子提供变化点
## 访问者 Visitor
- 对象模式:把作用于对象结构的操作封装到访问者中
- 对象结构相对稳定时便于新增操作;新增元素类型通常要修改访问者