Objective-C 类的依赖注入实践:降低类间耦合的 5 个关键步骤
·
Objective-C 依赖注入实践:降低类间耦合的 5 个关键步骤
依赖注入(DI)通过将依赖对象的创建与使用分离,显著降低类间耦合度。以下是 Objective-C 中的实践步骤:
1. 识别硬编码依赖
// 反例:直接在类内部实例化依赖
@implementation OrderService
- (void)processOrder {
DatabaseManager *dbManager = [[DatabaseManager alloc] init]; // 硬编码耦合
[dbManager saveOrder];
}
@end
关键操作:
- 审查
.m文件中的[[Class alloc] init]调用 - 定位需要解耦的核心依赖(如网络层、数据库层)
2. 抽象依赖协议
// 定义协议抽象依赖
@protocol PaymentProcessor <NSObject>
- (void)handlePayment:(double)amount;
@end
// 协议实现类
@implementation PayPalProcessor <PaymentProcessor>
- (void)handlePayment:(double)amount { /*...*/ }
@end
优势:
- 符合依赖倒置原则(DIP)
- 支持多态实现替换
3. 构造函数注入
// 通过初始化器注入依赖
@interface OrderService : NSObject
- (instancetype)initWithPaymentProcessor:(id<PaymentProcessor>)processor;
@end
@implementation OrderService {
id<PaymentProcessor> _paymentProcessor;
}
- (instancetype)initWithPaymentProcessor:(id<PaymentProcessor>)processor {
if (self = [super init]) {
_paymentProcessor = processor; // 注入依赖
}
return self;
}
- (void)checkout {
[_paymentProcessor handlePayment:100.0]; // 使用抽象接口
}
@end
使用场景:
- 必需依赖项
- 依赖关系在生命周期内不变
4. 属性注入
// 通过公开属性注入
@interface AnalyticsService : NSObject
@property (strong, nonatomic) id<EventTracker> tracker; // 可替换依赖
@end
// 使用时动态注入
AnalyticsService *analytics = [AnalyticsService new];
analytics.tracker = [[FirebaseTracker alloc] init]; // 运行时注入
适用场景:
- 可选依赖项
- 需要运行时动态替换实现
5. 依赖容器集成
// 使用 Typhoon 框架示例
@interface ApplicationAssembly : TyphoonAssembly
- (OrderService *)orderService;
- (id<PaymentProcessor>)paymentProcessor;
@end
@implementation ApplicationAssembly
- (OrderService *)orderService {
return [TyphoonDefinition withClass:[OrderService class]
configuration:^(TyphoonDefinition *definition) {
[definition injectProperty:@selector(paymentProcessor)
with:[self paymentProcessor]];
}];
}
- (id<PaymentProcessor>)paymentProcessor {
return [TyphoonDefinition withClass:[StripeProcessor class]];
}
@end
容器优势:
- 集中管理依赖关系
- 自动解决依赖链
- 支持单例/原型作用域控制
效果验证
// 单元测试示例(使用 OCMock)
- (void)testOrderProcessing {
// 1. 创建协议模拟对象
id mockProcessor = OCMProtocolMock(@protocol(PaymentProcessor));
// 2. 注入模拟依赖
OrderService *service = [[OrderService alloc] initWithPaymentProcessor:mockProcessor];
// 3. 验证交互行为
OCMExpect([mockProcessor handlePayment:100.0]);
[service checkout];
OCMVerifyAll(mockProcessor);
}
耦合度变化: $$ \text{耦合系数} = \frac{\text{直接依赖}}{\text{总类数}} \rightarrow 0.2 \text{(DI后)} \quad vs \quad 0.8 \text{(DI前)} $$
最佳实践
- 组合优于继承:通过 DI 实现对象组合
- 接口隔离:每个协议专注单一能力
- 循环依赖检测:使用
__weak打破强引用环 - 分层注入:基础设施层 → 领域层 → 表示层
通过这 5 步,可使模块间依赖变为可配置的弱连接,显著提升代码可测试性和架构灵活性。典型应用场景:服务层替换、测试替身注入、多环境配置切换。
更多推荐
所有评论(0)