在 iOS 开发中,设计模式是提高代码可维护性和可扩展性的重要手段。以下是 iOS 开发中最常用的 7 种设计模式详解:
一、MVC 模式(Model-View-Controller)
原理
苹果官方推荐模式,将应用分为:
- Model:数据层
- View:界面层
- Controller:业务逻辑层
优缺点
✅ 优点:
- 职责分离明确
- 官方框架原生支持
- 学习成本低
❌ 缺点:
- Controller 容易臃肿(Massive View Controller)
- View 和 Model 存在耦合
使用场景
小型项目或需要快速开发的场景
<代码示例>
less 代码解读复制代码// OC 实现
// Model
@interface User : NSObject
@property (nonatomic, copy) NSString *name;
@end
// View
@interface ProfileView : UIView
- (void)updateName:(NSString *)name;
@end
// Controller
@interface ProfileViewController : UIViewController
@property (strong, nonatomic) User *user;
@property (strong, nonatomic) ProfileView *profileView;
@end
@implementation
- (void)viewDidLoad {
[self.profileView updateName:self.user.name];
}
@end
swift 代码解读复制代码// Swift 实现
// Model
struct User {
let name: String
}
// View
class ProfileView: UIView {
func updateName(_ name: String) {
// 更新界面
}
}
// Controller
class ProfileViewController: UIViewController {
var user: User!
var profileView: ProfileView!
override func viewDidLoad() {
super.viewDidLoad()
profileView.updateName(user.name)
}
}
二、MVVM 模式(Model-View-ViewModel)
原理
- ViewModel:处理业务逻辑
- View:界面展示
- 数据绑定实现自动更新
优缺点
✅ 优点:
- 更好的职责分离
- 便于单元测试
- 减少 Controller 体积
❌ 缺点:
- 数据绑定增加复杂度
- 需要额外学习响应式编程
使用场景
中大型项目,需要复杂业务逻辑的场景
<代码示例>
swift 代码解读复制代码// Swift 实现(使用 Combine)
class UserViewModel {
@Published var userName: String = ""
func loadUser() {
// 网络请求...
userName = "John"
}
}
class ProfileViewController: UIViewController {
private var viewModel = UserViewModel()
private var cancellables = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
viewModel.$userName
.sink { [weak self] name in
self?.updateUI(name: name)
}
.store(in: &cancellables)
}
private func updateUI(name: String) {
// 更新界面
}
}
objectivec 代码解读复制代码// OC 实现(使用 KVO)
// ViewModel
@interface UserViewModel : NSObject
@property (nonatomic, strong) NSString *userName;
- (void)loadUser;
@end
// Controller
@interface ProfileViewController : UIViewController
@property (strong, nonatomic) UserViewModel *viewModel;
@end
@implementation
- (void)viewDidLoad {
[self.viewModel addObserver:self
forKeyPath:@"userName"
options:NSKeyValueObservingOptionNew
context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:@"userName"]) {
[self updateUIWithName:change[NSKeyValueChangeNewKey]];
}
}
@end
三、单例模式(Singleton)
原理
确保类只有一个实例,并提供全局访问点
优缺点
✅ 优点:
- 全局访问方便
- 节省资源
❌ 缺点:
- 难以单元测试
- 可能造成全局状态污染
使用场景
需要全局唯一实例的场景(如日志管理、网络监控)
<代码示例>
csharp 代码解读复制代码// Swift 实现
class NetworkManager {
static let shared = NetworkManager()
private init() {}
func request() {
// 网络请求...
}
}
// 使用
NetworkManager.shared.request()
less 代码解读复制代码// OC 实现
@interface NetworkManager : NSObject
+ (instancetype)shared;
@end
@implementation
+ (instancetype)shared {
static NetworkManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
@end
四、观察者模式(Observer)
原理
对象间定义一对多的依赖关系,当一个对象状态改变时,所有依赖者都会收到通知
优缺点
✅ 优点:
- 解耦观察者与被观察者
- 支持广播通信
❌ 缺点:
- 内存泄漏风险(未及时移除观察者)
- 调试困难
使用场景
需要实现事件通知机制的场景
<代码示例>
php 代码解读复制代码// Swift 使用 NotificationCenter
let notificationName = Notification.Name("DataUpdated")
// 发送通知
NotificationCenter.default.post(name: notificationName, object: nil)
// 接收通知
NotificationCenter.default.addObserver(
self,
selector: #selector(handleNotification),
name: notificationName,
object: nil
)
less 代码解读复制代码// OC 实现 KVO
@interface DataModel : NSObject
@property (nonatomic, strong) NSString *data;
@end
// 观察者
[dataModel addObserver:self
forKeyPath:@"data"
options:NSKeyValueObservingOptionNew
context:nil];
五、工厂模式(Factory)
原理
通过工厂类创建对象,而不是直接实例化具体类
优缺点
✅ 优点:
- 解耦对象创建和使用
- 方便扩展新产品
❌ 缺点:
- 增加代码复杂度
- 需要设计良好的继承体系
使用场景
需要灵活创建对象的场景(如不同主题切换)
<代码示例>
swift 代码解读复制代码// Swift 实现
protocol Button {
func render()
}
class iOSButton: Button {
func render() { print("iOS Style Button") }
}
class AndroidButton: Button {
func render() { print("Material Design Button") }
}
enum Platform {
case iOS, android
}
class ButtonFactory {
static func createButton(for platform: Platform) -> Button {
switch platform {
case .iOS: return iOSButton()
case .android: return AndroidButton()
}
}
}
// 使用
let button = ButtonFactory.createButton(for: .iOS)
less 代码解读复制代码// OC 实现
@protocol Button
- (void)render;
@end
@interface iOSButton : NSObject
@end
@implementation
- (void)render { NSLog(@"iOS Style Button"); }
@end
typedef NS_ENUM(NSUInteger, Platform) {
PlatformiOS,
PlatformAndroid
};
@interface ButtonFactory : NSObject
+ (id
@end
@implementation
+ (id
switch (platform) {
case PlatformiOS: return [iOSButton new];
case PlatformAndroid: return [AndroidButton new];
}
}
@end
六、代理模式(Delegate)
原理
定义一个协议,委托方通过协议与代理方通信
优缺点
✅ 优点:
- 解耦委托方和代理方
- 支持多个代理
❌ 缺点:
- 协议方法需要逐层传递
- 可能产生长链式调用
使用场景
需要回调机制的场景(如 UITableView 的点击事件)
<代码示例>
swift 代码解读复制代码// Swift 实现
protocol ImageDownloaderDelegate: AnyObject {
func didFinishDownloading(image: UIImage)
}
class ImageDownloader {
weak var delegate: ImageDownloaderDelegate?
func download() {
// 下载完成...
delegate?.didFinishDownloading(image: UIImage())
}
}
class ViewController: ImageDownloaderDelegate {
let downloader = ImageDownloader()
init() {
downloader.delegate = self
}
func didFinishDownloading(image: UIImage) {
// 处理图片
}
}
less 代码解读复制代码// OC 实现
@protocol ImageDownloaderDelegate
- (void)didFinishDownloadingImage:(UIImage *)image;
@end
@interface ImageDownloader : NSObject
@property (weak) id delegate;
- (void)download;
@end
@implementation
- (void)download {
// 下载完成...
[self.delegate didFinishDownloadingImage:[UIImage new]];
}
@end
七、策略模式(Strategy)
原理
定义算法族,使算法可以互相替换
优缺点
✅ 优点:
- 避免多重条件语句
- 方便扩展新算法
❌ 缺点:
- 增加对象数量
- 需要客户端了解不同策略
使用场景
需要动态切换算法的场景(如排序算法选择)
<代码示例>
swift 代码解读复制代码// Swift 实现
protocol PaymentStrategy {
func pay(amount: Double) -> Bool
}
class Alipay: PaymentStrategy {
func pay(amount: Double) -> Bool {
print("支付宝支付")
return true
}
}
class WechatPay: PaymentStrategy {
func pay(amount: Double) -> Bool {
print("微信支付")
return true
}
}
class PaymentContext {
private var strategy: PaymentStrategy
init(strategy: PaymentStrategy) {
self.strategy = strategy
}
func executePayment(amount: Double) -> Bool {
return strategy.pay(amount: amount)
}
}
// 使用
let context = PaymentContext(strategy: Alipay())
context.executePayment(amount: 100)
less 代码解读复制代码// OC 实现
@protocol PaymentStrategy
- (BOOL)payAmount:(CGFloat)amount;
@end
@interface Alipay : NSObject
@end
@implementation
- (BOOL)payAmount:(CGFloat)amount {
NSLog(@"支付宝支付");
return YES;
}
@end
@interface PaymentContext : NSObject
- (instancetype)initWithStrategy:(id)strategy;
- (BOOL)executePayment:(CGFloat)amount;
@end
@interface PaymentContext ()
@property (strong) id<PaymentStrategy> strategy;
@end
@implementation
- (BOOL)executePayment:(CGFloat)amount {
return [self.strategy payAmount:amount];
}
@end
总结建议
- 简单场景优先使用 MVC
- 复杂业务逻辑推荐 MVVM + 响应式编程
- 全局服务使用单例但要严格控制
- 组件通信优先选择代理模式
- 动态行为切换使用策略模式
- 对象创建复杂时采用工厂模式
- 跨模块通知使用观察者模式
每种模式都有其适用场景,实际开发中通常会组合使用多种设计模式。建议根据具体需求选择最合适的模式,避免为了使用模式而过度设计。
评论记录:
回复评论: