从0到1掌握iOS设计模式:架构师私藏的实战指南
你还在为臃肿的iOS项目重构发愁?面对复杂业务逻辑无从下手?本文将通过Trip-to-iOS-Design-Patterns项目,带你系统掌握设计模式在iOS开发中的落地实践,从理论到代码实现,一站式解决架构设计难题。
读完本文你将获得:
- 23种设计模式的iOS实战场景分析
- 基于Objective-C和Swift的双语言实现对比
- 单例、代理、观察者等高频模式的代码模板
- 大型项目架构演进的完整路线图
- 5个主流App的架构设计拆解案例
项目概述:iOS架构设计的学习宝库
Trip-to-iOS-Design-Patterns是一个专注于iOS设计模式实践的开源项目,通过Objective-C和Swift两种语言实现了常见设计模式的应用场景。项目提供了完整的代码示例和架构分析,帮助开发者理解如何在实际项目中运用设计模式解决复杂业务问题。
项目核心结构:
Trip-to-iOS-Design-Patterns/
├── README.md # 项目文档与资源索引
└── SimpleCode/
├── BlueLibrary-Objc/ # Objective-C实现示例
└── BlueLibrary-Swift/ # Swift实现示例
设计模式基础:从理论到iOS实践
什么是设计模式
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计中常见问题的最佳解决方案,是面向对象编程思想的高度提炼。
iOS开发中常用的设计模式可分为三大类:
mindmap
root((设计模式))
创建型模式
单例模式
工厂模式
建造者模式
结构型模式
代理模式
适配器模式
组合模式
行为型模式
观察者模式
命令模式
策略模式
iOS开发中的设计模式应用现状
根据项目README.md统计,iOS开发中最常使用的设计模式及其出现频率:
| 设计模式 | 出现频率 | 主要应用场景 | 难度评级 |
|---|---|---|---|
| 单例模式 | ★★★★★ | 网络请求、数据存储 | 简单 |
| 代理模式 | ★★★★★ | 视图控制器通信 | 简单 |
| 观察者模式 | ★★★★☆ | 数据绑定、状态监听 | 中等 |
| MVC模式 | ★★★★★ | 界面架构设计 | 简单 |
| 工厂模式 | ★★★☆☆ | 对象创建管理 | 中等 |
| 策略模式 | ★★☆☆☆ | 算法切换、主题切换 | 中等 |
| 装饰器模式 | ★★☆☆☆ | 控件功能扩展 | 较难 |
核心设计模式实战:以BlueLibrary项目为例
单例模式(Singleton)
单例模式是保证一个类仅有一个实例,并提供一个访问它的全局访问点。在iOS开发中,单例模式被广泛应用于网络请求、数据存储等核心服务类。
Objective-C实现:
// LibraryAPI.h
#import <Foundation/Foundation.h>
@class Album;
@interface LibraryAPI : NSObject
+ (LibraryAPI*)sharedInstance;
- (NSArray*)getAlbums;
- (void)addAlbum:(Album*)album atIndex:(NSInteger)index;
- (void)deleteAlbumAtIndex:(NSInteger)index;
@end
// LibraryAPI.m
@implementation LibraryAPI
+ (LibraryAPI *)sharedInstance {
static LibraryAPI *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
// 其他方法实现...
@end
Swift实现:
class LibraryAPI {
static let sharedInstance = LibraryAPI()
// 私有化构造方法,防止外部实例化
private init() {}
func getAlbums() -> [Album] {
// 实现代码
}
func addAlbum(_ album: Album, at index: Int) {
// 实现代码
}
}
应用场景分析:
单例模式在项目中的典型应用是LibraryAPI类,它封装了应用的核心业务逻辑,通过单例模式确保整个应用中只有一个实例,避免了数据不一致的问题。
使用单例模式的注意事项:
- 避免在多线程环境下使用 mutable 的单例对象
- 单例对象的生命周期与应用一致,注意内存占用
- 单元测试时单例可能会导致测试用例相互干扰
代理模式(Delegate)
代理模式(Delegate Pattern)是iOS开发中最常用的设计模式之一,它定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。
Objective-C中的代理实现:
// HorizontalScroller.h
#import <UIKit/UIKit.h>
@protocol HorizontalScrollerDelegate <NSObject>
- (NSInteger)numberOfViewsForHorizontalScroller:(HorizontalScroller *)scroller;
- (UIView *)horizontalScroller:(HorizontalScroller *)scroller viewAtIndex:(NSInteger)index;
- (void)horizontalScroller:(HorizontalScroller *)scroller didSelectViewAtIndex:(NSInteger)index;
@end
@interface HorizontalScroller : UIView
@property (nonatomic, weak) id<HorizontalScrollerDelegate> delegate;
- (void)reload;
@end
Swift中的代理实现:
protocol HorizontalScrollerDelegate: AnyObject {
func numberOfViews(for horizontalScroller: HorizontalScroller) -> Int
func horizontalScroller(_ scroller: HorizontalScroller, viewAt index: Int) -> UIView
func horizontalScroller(_ scroller: HorizontalScroller, didSelectViewAt index: Int)
}
class HorizontalScroller: UIView {
weak var delegate: HorizontalScrollerDelegate?
func reload() {
// 实现代码
}
}
代理模式的最佳实践:
- 代理方法命名应包含发送者信息,如
horizontalScroller:didSelectViewAtIndex: - 可选方法需用
@optional标记(Objective-C)或扩展实现(Swift) - 代理属性应使用
weak修饰,避免循环引用 - 复杂交互场景可考虑使用Block+协议的混合方式
观察者模式(Observer)
观察者模式(Observer Pattern)定义了对象之间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。
在iOS开发中,观察者模式的典型实现包括:
- NotificationCenter(通知中心)
- KVO(键值观察)
- 自定义观察者模式
KVO实现示例:
// 注册观察者
[album addObserver:self
forKeyPath:@"name"
options:NSKeyValueObservingOptionNew
context:NULL];
// 实现观察回调
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:@"name"]) {
NSLog(@"Album name changed to: %@", change[NSKeyValueChangeNewKey]);
[self updateAlbumNameLabel];
}
}
// 移除观察者
- (void)dealloc {
[album removeObserver:self forKeyPath:@"name"];
}
NotificationCenter实现示例:
// 注册通知
NotificationCenter.default.addObserver(self,
selector: #selector(handleAlbumUpdated(_:)),
name: NSNotification.Name("AlbumUpdated"),
object: nil)
// 实现通知处理
@objc func handleAlbumUpdated(_ notification: Notification) {
guard let album = notification.object as? Album else { return }
print("Album updated: \(album.name)")
}
// 发送通知
NotificationCenter.default.post(name: NSNotification.Name("AlbumUpdated"),
object: album)
项目代码深度解析:BlueLibrary架构设计
整体架构概览
BlueLibrary项目采用了经典的三层架构,通过设计模式实现了各层之间的解耦,使代码具有良好的可维护性和扩展性。
flowchart TD
A[ViewController] -->|使用| B[LibraryAPI]
B -->|组合| C[PersistencyManager]
B -->|组合| D[HTTPClient]
C -->|本地存储| E[CoreData/文件系统]
D -->|网络请求| F[服务器API]
主要组件功能:
- ViewController:负责UI展示和用户交互
- LibraryAPI:单例类,封装核心业务逻辑
- PersistencyManager:处理本地数据持久化
- HTTPClient:处理网络请求
依赖注入模式的应用
项目通过依赖注入(Dependency Injection)模式降低了组件间的耦合度,使代码更易于测试和维护。
依赖注入实现示例:
// LibraryAPI.h
@interface LibraryAPI : NSObject
// 通过构造方法注入依赖
- (instancetype)initWithPersistencyManager:(PersistencyManager *)persistencyManager
httpClient:(HTTPClient *)httpClient;
@end
// LibraryAPI.m
@implementation LibraryAPI
- (instancetype)initWithPersistencyManager:(PersistencyManager *)persistencyManager
httpClient:(HTTPClient *)httpClient {
self = [super init];
if (self) {
_persistencyManager = persistencyManager;
_httpClient = httpClient;
}
return self;
}
@end
这种设计的优势:
- 便于单元测试时替换真实对象为Mock对象
- 组件间依赖关系清晰可见
- 符合单一职责原则,每个类只负责自己的功能
数据模型设计
项目中的Album类采用了装饰器模式,通过分类(Category)为模型添加了额外功能,而不修改原有类的实现。
Objective-C分类实现:
// Album+TableRepresentation.h
#import "Album.h"
@interface Album (TableRepresentation)
- (NSDictionary *)tr_tableRepresentation;
@end
// Album+TableRepresentation.m
@implementation Album (TableRepresentation)
- (NSDictionary *)tr_tableRepresentation {
return @{
@"titles": @[@"Title", @"Artist", @"Genre", @"Year"],
@"values": @[self.title, self.artist, self.genre, self.year]
};
}
@end
Swift扩展实现:
extension Album {
func tableRepresentation() -> [String: [String]] {
return [
"titles": ["Title", "Artist", "Genre", "Year"],
"values": [title, artist, genre, year]
]
}
}
设计模式实战:从需求到代码实现
案例1:网络请求模块设计
需求:实现一个网络请求模块,要求:
- 全局唯一实例,避免重复创建
- 支持GET/POST请求
- 支持图片下载
- 可缓存网络请求结果
解决方案:采用单例模式+策略模式
// HTTPClient.h
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, RequestCachePolicy) {
RequestCachePolicyNone,
RequestCachePolicyMemory,
RequestCachePolicyDisk
};
@interface HTTPClient : NSObject
+ (instancetype)sharedClient;
- (id)getRequest:(NSString*)url
cachePolicy:(RequestCachePolicy)policy
completion:(void(^)(id response, NSError *error))completion;
- (id)postRequest:(NSString*)url
parameters:(NSDictionary*)parameters
completion:(void(^)(id response, NSError *error))completion;
- (void)downloadImage:(NSString*)url
completion:(void(^)(UIImage *image, NSError *error))completion;
@end
案例2:图片浏览器设计
需求:实现一个图片浏览器,要求:
- 支持左右滑动切换图片
- 支持图片下载进度显示
- 支持缩放查看
- 支持删除图片
解决方案:采用组合模式+观察者模式
class ImageBrowserViewController: UIViewController {
var imageBrowser: HorizontalScroller!
var images: [ImageModel] = []
override func viewDidLoad() {
super.viewDidLoad()
setupImageBrowser()
loadImages()
}
private func setupImageBrowser() {
imageBrowser = HorizontalScroller()
imageBrowser.delegate = self
view.addSubview(imageBrowser)
// 布局代码...
}
private func loadImages() {
imageBrowser.reload()
}
}
extension ImageBrowserViewController: HorizontalScrollerDelegate {
func numberOfViews(for horizontalScroller: HorizontalScroller) -> Int {
return images.count
}
func horizontalScroller(_ scroller: HorizontalScroller, viewAt index: Int) -> UIView {
let imageView = ImageView()
imageView.imageModel = images[index]
imageView.delegate = self
return imageView
}
// 其他代理方法...
}
大型项目架构演进:从MVC到组件化
iOS架构模式对比
| 架构模式 | 核心思想 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| MVC | 模型-视图-控制器 | 简单直观,Apple官方推荐 | 控制器臃肿,测试困难 | 小型项目,快速迭代 |
| MVVM | 模型-视图-视图模型 | 职责清晰,易于测试 | 学习曲线陡峭 | 中大型项目,复杂UI |
| VIPER | 视图-交互器-演示器-实体-路由 | 高内聚低耦合,可测试性好 | 代码量大,结构复杂 | 大型项目,团队协作 |
| MVCS | 模型-视图-控制器-存储 | 分离数据处理逻辑 | 增加了代码复杂度 | 数据密集型应用 |
组件化架构设计
随着项目规模增长,单体应用会面临编译慢、团队协作困难等问题,组件化架构应运而生。
组件化架构的核心思想是将App按照功能划分为独立的组件,组件间通过协议通信,实现高内聚低耦合。
flowchart LR
App壳工程 --> 路由中心
路由中心 -->|协议| 首页组件
路由中心 -->|协议| 我的组件
路由中心 -->|协议| 消息组件
路由中心 -->|协议| 公共组件
公共组件 --> 网络模块
公共组件 --> 工具类
公共组件 --> 基础UI
组件化实现步骤:
- 按业务功能划分组件边界
- 设计组件间通信协议
- 实现路由中心管理组件跳转
- 构建私有Pods管理组件依赖
- 实现组件化测试方案
实战案例:主流App架构设计拆解
微信iOS客户端架构
微信作为国民级App,其架构经历了多次演进,从早期的MVC到现在的组件化架构。
核心特点:
- 采用插件化架构,支持动态更新
- 基于TCP的自研IM协议
- 分层设计,业务与基础库分离
- 轻量级MVVM模式
支付宝架构设计
支付宝作为金融类App,对安全性和稳定性要求极高,其架构设计有以下特点:
- 基于插件化的微内核架构
- 安全沙箱机制保护敏感操作
- 服务化设计,支持异地多活
- 动态化方案实现热修复
抖音架构设计
抖音作为短视频App,对性能和用户体验有极致追求:
- 基于组件化的分层架构
- 自研播放器内核
- 图片/视频缓存策略优化
- 首屏加载性能优化方案
设计模式学习资源推荐
经典书籍
-
《设计模式:可复用面向对象软件的基础》(GoF著作)
- 设计模式的开山之作,系统介绍了23种设计模式
-
《Objective-C编程之道:iOS设计模式解析》
- 专为iOS开发者打造的设计模式书籍,结合Objective-C语言特性
-
《Swift设计模式》
- 基于Swift语言的设计模式实践指南,包含大量代码示例
在线资源
-
iOS Design Patterns(raywenderlich.com)
- 从iOS视角解读常用设计模式,提供完整代码示例
-
Cocoa Design Patterns(Apple官方文档)
- Apple官方对Cocoa框架中设计模式的解析
-
objccn.io(Objective-C中国)
- 包含大量高质量的iOS架构与设计模式文章
总结与展望
设计模式是iOS开发进阶的必备技能,掌握设计模式不仅能提高代码质量,还能帮助开发者从更高维度思考架构设计。Trip-to-iOS-Design-Patterns项目通过实战代码展示了设计模式在iOS开发中的应用,是学习设计模式的绝佳资源。
随着SwiftUI和Combine框架的普及,函数式编程思想在iOS开发中逐渐兴起,未来设计模式的应用也将呈现新的形式。但无论技术如何变化,设计模式背后的面向对象思想和软件设计原则是永恒的。
作为开发者,我们应该:
- 深入理解设计模式的本质,而非死记硬背实现
- 结合具体业务场景选择合适的设计模式
- 持续学习优秀开源项目的架构设计
- 在实践中不断反思和优化代码结构
希望本文能帮助你更好地理解和应用设计模式,构建出高质量的iOS应用。如果你有任何问题或建议,欢迎在评论区留言讨论。
附录:设计模式速查表
| 类型 | 设计模式 | Objective-C实现 | Swift实现 | 项目应用 |
|---|---|---|---|---|
| 创建型 | 单例模式 | dispatch_once | static let | LibraryAPI |
| 创建型 | 工厂模式 | 类方法创建 | 便利构造器 | AlbumFactory |
| 结构型 | 代理模式 | @protocol | Protocol | HorizontalScroller |
| 结构型 | 适配器模式 | 继承+组合 | 扩展+协议 | APIDataAdapter |
| 行为型 | 观察者模式 | KVO/Notification | KVO/Notification | Album变化监听 |
| 行为型 | 命令模式 | Target-Action | Closure | 按钮点击事件 |
| 行为型 | 策略模式 | 协议+多实现 | 协议+枚举 | 网络缓存策略 |
kernelopenEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。C0134
let_datasetLET数据集 基于全尺寸人形机器人 Kuavo 4 Pro 采集,涵盖多场景、多类型操作的真实世界多任务数据。面向机器人操作、移动与交互任务,支持真实环境下的可扩展机器人学习00
mindquantumMindQuantum is a general software library supporting the development of applications for quantum computation.Python059
PaddleOCR-VLPaddleOCR-VL 是一款顶尖且资源高效的文档解析专用模型。其核心组件为 PaddleOCR-VL-0.9B,这是一款精简却功能强大的视觉语言模型(VLM)。该模型融合了 NaViT 风格的动态分辨率视觉编码器与 ERNIE-4.5-0.3B 语言模型,可实现精准的元素识别。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
AgentCPM-ReportAgentCPM-Report是由THUNLP、中国人民大学RUCBM和ModelBest联合开发的开源大语言模型智能体。它基于MiniCPM4.1 80亿参数基座模型构建,接收用户指令作为输入,可自主生成长篇报告。Python00