设计模式是软件开发中经过验证的解决特定问题的最佳实践。在Android开发中,恰当地应用设计模式可以显著提高代码的可维护性、可扩展性和可测试性。
一、设计模式三大类
设计模式主要分为三类,每一类解决不同领域的问题:
1. 创建型设计模式(Creational Patterns)
专注于对象的创建机制,帮助系统以适当的方式创建、组合和表示对象。
2. 结构型设计模式(Structural Patterns)
关注类和对象的组合,形成更大的结构,并保持结构的灵活和高效。
3. 行为型设计模式(Behavioral Patterns)
专注于对象之间的通信,以及对象的职责分配和算法抽象。
二、详细介绍各类设计模式
创建型设计模式
模式名称 | 描述 | Android使用场景 |
---|---|---|
单例模式 (Singleton) | 确保一个类只有一个实例,并提供全局访问点 | - SharedPreferences实例 - 数据库连接管理 - 系统服务访问 |
工厂方法模式 (Factory Method) | 定义一个创建对象的接口,让子类决定实例化哪个类 | - Fragment的创建 - Intent的创建 - 视图创建器 |
抽象工厂模式 (Abstract Factory) | 提供一个创建相关对象家族的接口,无需指定具体类 | - 不同主题UI组件族 - 跨平台组件创建 |
建造者模式 (Builder) | 分步骤构建复杂对象,允许用不同的方式创建 | - AlertDialog.Builder - Retrofit配置 - NotificationCompat.Builder |
原型模式 (Prototype) | 通过复制现有实例来创建新对象 | - 深度复制复杂对象 - UI元素克隆 |
结构型设计模式
模式名称 | 描述 | Android使用场景 |
---|---|---|
适配器模式 (Adapter) | 将一个类的接口转换成客户期望的另一个接口 | - RecyclerView.Adapter - ArrayAdapter - 旧API适配 |
桥接模式 (Bridge) | 将抽象与实现分离,使它们可以独立变化 | - 不同设备屏幕的渲染 - 支持多种数据源的View |
组合模式 (Composite) | 将对象组合成树形结构表示"部分-整体"层次 | - View层级结构 - 复杂UI组件 |
装饰模式 (Decorator) | 动态给对象添加额外的职责 | - ContextWrapper - InputStreamReader |
外观模式 (Facade) | 为子系统提供一个统一的高层接口 | - Camera API包装 - 复杂功能的简化接口 |
享元模式 (Flyweight) | 通过共享技术有效支持大量细粒度对象 | - 字符串常量池 - 图片资源缓存 |
代理模式 (Proxy) | 为其他对象提供一个替身或占位符以控制对这个对象的访问 | - 图片懒加载 - 远程服务代理 - 权限检查 |
行为型设计模式
模式名称 | 描述 | Android使用场景 |
---|---|---|
责任链模式 (Chain of Responsibility) | 多个对象处理请求,避免请求发送者和接收者耦合 | - 事件分发机制 - 拦截器链 - 中间件处理 |
命令模式 (Command) | 将请求封装为一个对象,使不同请求参数化 | - 撤销/重做功能 - 队列请求 - 任务调度 |
解释器模式 (Interpreter) | 定义语言的语法表示,解释相应的句子 | - 简单表达式计算 - 规则引擎 |
迭代器模式 (Iterator) | 提供一种方法顺序访问一个聚合对象中的各个元素 | - Cursor遍历 - 集合遍历 |
中介者模式 (Mediator) | 封装一组对象如何交互,集中相互通信的复杂性 | - Fragment通信 - ViewModel作为UI和数据层中介 |
备忘录模式 (Memento) | 捕获对象内部状态,在将来可以恢复 | - Activity状态保存与恢复 - 编辑器撤销功能 |
观察者模式 (Observer) | 定义对象间的依赖关系,当一个对象改变时,依赖它的对象都得到通知 | - LiveData - BroadcastReceiver - EventBus |
状态模式 (State) | 允许对象在内部状态改变时改变行为 | - 播放器状态管理 - 网络连接状态 |
策略模式 (Strategy) | 定义一系列算法,封装每个算法,并使它们可互换 | - 不同布局管理器 - 多种排序算法 - 图片加载策略 |
模板方法模式 (Template Method) | 定义算法骨架,延迟某些步骤到子类 | - Activity生命周期 - AsyncTask - RecyclerView.Adapter |
访问者模式 (Visitor) | 表示作用于对象结构的操作,可在不改变元素的类的前提下定义新的操作 | - 注解处理 - 复杂对象结构处理 |
三、如何选择适当的设计模式
要快速确定使用哪种设计模式,可以遵循以下步骤:
-
明确问题本质:
- 是创建对象的问题?考虑创建型模式
- 是对象结构组织问题?考虑结构型模式
- 是对象交互和职责分配问题?考虑行为型模式
-
提问以缩小范围:
创建对象相关:
- 需要控制类的实例数量?→ 单例模式
- 需要根据条件创建不同但相关的对象?→ 工厂方法模式
- 需要创建一组相关对象?→ 抽象工厂模式
- 对象构建过程复杂或需要分步构建?→ 建造者模式
- 基于现有对象创建新对象?→ 原型模式
结构组织相关:
- 需要使不兼容的接口协同工作?→ 适配器模式
- 希望抽象和实现可以独立变化?→ 桥接模式
- 需要表示对象的层次结构?→ 组合模式
- 需要动态添加功能到对象?→ 装饰模式
- 希望简化复杂子系统?→ 外观模式
- 需要高效共享细粒度对象?→ 享元模式
- 需要控制对对象的访问?→ 代理模式
对象交互相关:
- 多个对象可处理请求且不知道谁会处理?→ 责任链模式
- 需要参数化和队列化请求?→ 命令模式
- 需要顺序访问集合元素而不暴露内部结构?→ 迭代器模式
- 需要对象间松散耦合通信?→ 观察者模式
- 对象行为依赖其状态?→ 状态模式
- 需要在运行时选择算法?→ 策略模式
- 算法有固定结构但某些步骤在子类中实现?→ 模板方法模式
四、实用决策图
下面是一个简化的决策流程图,帮助快速选择合适的设计模式:
markdown
问题类型
├── 创建对象
│ ├── 单个实例 → 单例模式
│ ├── 根据条件创建不同对象 → 工厂方法模式
│ ├── 创建对象族 → 抽象工厂模式
│ ├── 复杂对象分步构建 → 建造者模式
│ └── 基于已有对象创建 → 原型模式
│
├── 结构组织
│ ├── 接口不兼容 → 适配器模式
│ ├── 抽象与实现分离 → 桥接模式
│ ├── 树形结构 → 组合模式
│ ├── 动态扩展功能 → 装饰模式
│ ├── 简化复杂系统 → 外观模式
│ ├── 共享细粒度对象 → 享元模式
│ └── 控制访问 → 代理模式
│
└── 对象交互
├── 链式处理请求 → 责任链模式
├── 封装请求为对象 → 命令模式
├── 顺序访问集合元素 → 迭代器模式
├── 对象状态变化通知依赖者 → 观察者模式
├── 根据状态改变行为 → 状态模式
├── 可互换算法 → 策略模式
└── 定义算法骨架 → 模板方法模式
在实际开发中,多种设计模式常常结合使用,创建更加灵活和强大的应用架构。深入理解每种模式的优缺点和适用场景,是高效应用设计模式的关键。