面试题答案
一键面试依赖注入概念
依赖注入(Dependency Injection,简称DI)是一种设计模式,通过将对象所依赖的外部对象传递给该对象,而不是让对象自己创建或查找依赖对象,从而实现解耦,提高代码的可维护性和可测试性。
管理依赖关系步骤
- 定义协议:为每个模块定义协议,模块通过协议进行交互,而不是直接依赖具体实现类。
- 传递依赖:在需要使用依赖的模块中,通过构造函数、属性或方法参数的方式接收依赖对象。
关键代码示例
- 定义协议:
// 模块B协议
@protocol ModuleBProtocol <NSObject>
// 模块B相关方法声明
@end
// 模块C协议
@protocol ModuleCProtocol <NSObject>
// 模块C相关方法声明
@end
// 模块D协议
@protocol ModuleDProtocol <NSObject>
// 模块D相关方法声明
@end
// 模块E协议
@protocol ModuleEProtocol <NSObject>
// 模块E相关方法声明
@end
// 模块F协议
@protocol ModuleFProtocol <NSObject>
// 模块F相关方法声明
@end
// 模块G协议
@protocol ModuleGProtocol <NSObject>
// 模块G相关方法声明
@end
- 模块实现:
// 模块B实现
@interface ModuleB : NSObject <ModuleBProtocol>
@property (nonatomic, strong) id<ModuleEProtocol> moduleE;
@property (nonatomic, strong) id<ModuleFProtocol> moduleF;
- (instancetype)initWithModuleE:(id<ModuleEProtocol>)moduleE moduleF:(id<ModuleFProtocol>)moduleF;
@end
@implementation ModuleB
- (instancetype)initWithModuleE:(id<ModuleEProtocol>)moduleE moduleF:(id<ModuleFProtocol>)moduleF {
self = [super init];
if (self) {
_moduleE = moduleE;
_moduleF = moduleF;
}
return self;
}
@end
// 模块D实现
@interface ModuleD : NSObject <ModuleDProtocol>
@property (nonatomic, strong) id<ModuleGProtocol> moduleG;
- (instancetype)initWithModuleG:(id<ModuleGProtocol>)moduleG;
@end
@implementation ModuleD
- (instancetype)initWithModuleG:(id<ModuleGProtocol>)moduleG {
self = [super init];
if (self) {
_moduleG = moduleG;
}
return self;
}
@end
- 模块A使用依赖注入:
@interface ModuleA : NSObject
@property (nonatomic, strong) id<ModuleBProtocol> moduleB;
@property (nonatomic, strong) id<ModuleCProtocol> moduleC;
@property (nonatomic, strong) id<ModuleDProtocol> moduleD;
- (instancetype)initWithModuleB:(id<ModuleBProtocol>)moduleB moduleC:(id<ModuleCProtocol>)moduleC moduleD:(id<ModuleDProtocol>)moduleD;
@end
@implementation ModuleA
- (instancetype)initWithModuleB:(id<ModuleBProtocol>)moduleB moduleC:(id<ModuleCProtocol>)moduleC moduleD:(id<ModuleDProtocol>)moduleD {
self = [super init];
if (self) {
_moduleB = moduleB;
_moduleC = moduleC;
_moduleD = moduleD;
}
return self;
}
@end
- 使用示例:
// 创建模块E、F、G实例
id<ModuleEProtocol> moduleE = [[ModuleE alloc] init];
id<ModuleFProtocol> moduleF = [[ModuleF alloc] init];
id<ModuleGProtocol> moduleG = [[ModuleG alloc] init];
// 创建模块B、D实例并注入依赖
id<ModuleBProtocol> moduleB = [[ModuleB alloc] initWithModuleE:moduleE moduleF:moduleF];
id<ModuleDProtocol> moduleD = [[ModuleD alloc] initWithModuleG:moduleG];
// 创建模块C实例
id<ModuleCProtocol> moduleC = [[ModuleC alloc] init];
// 创建模块A实例并注入依赖
ModuleA *moduleA = [[ModuleA alloc] initWithModuleB:moduleB moduleC:moduleC moduleD:moduleD];
通过上述方式,利用依赖注入管理了复杂的依赖关系,使得每个模块的职责清晰,可维护性和可测试性得到提升。在测试时,可以很方便地替换具体依赖对象为模拟对象,从而对单个模块进行独立测试。