面试题答案
一键面试常见应用场景
- 依赖注入:在设计对象之间的依赖关系时,使用对象化协议可以方便地将不同实现类通过协议类型进行注入,提高代码的可测试性和可维护性。例如,一个视图控制器需要一个数据加载器,通过协议定义数据加载的方法,然后可以在运行时根据不同情况注入不同的数据加载实现类。
- 多态实现:可以根据不同的业务场景,让多个类遵循同一个协议,通过对象化协议来统一处理这些遵循协议的类实例,实现多态效果。
- 框架扩展:在开发框架时,使用对象化协议可以提供一种灵活的扩展机制,外部开发者可以通过遵循框架定义的协议来扩展框架功能。
具体例子
假设我们正在开发一个电商应用,其中有一个商品展示模块。商品数据可能从不同的数据源获取,比如本地数据库、网络接口等。
- 定义协议
@protocol ProductDataSource <NSObject>
- (NSArray *)fetchProducts;
@end
- 对象化协议
Protocol *productDataSourceProto = @protocol(ProductDataSource);
- 不同数据源实现类
- 本地数据源
@interface LocalProductDataSource : NSObject <ProductDataSource>
- (NSArray *)fetchProducts {
// 从本地数据库获取商品数据逻辑
return @[];
}
@end
- 网络数据源
@interface NetworkProductDataSource : NSObject <ProductDataSource>
- (NSArray *)fetchProducts {
// 从网络获取商品数据逻辑
return @[];
}
@end
- 商品展示视图控制器
@interface ProductViewController : UIViewController {
id<ProductDataSource> dataSource;
}
- (instancetype)initWithDataSource:(id<ProductDataSource>)source {
if (self = [super init]) {
dataSource = source;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *products = [dataSource fetchProducts];
// 展示商品逻辑
}
@end
- 使用场景 在应用启动时,可以根据网络状态或者用户设置来决定使用哪种数据源。
if ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable) {
NetworkProductDataSource *networkSource = [[NetworkProductDataSource alloc] init];
ProductViewController *vc = [[ProductViewController alloc] initWithDataSource:networkSource];
} else {
LocalProductDataSource *localSource = [[LocalProductDataSource alloc] init];
ProductViewController *vc = [[ProductViewController alloc] initWithDataSource:localSource];
}
通过这种对象化协议的方式,我们实现了商品展示模块与数据源的解耦,使得代码在数据源变更时更加灵活,不需要对商品展示视图控制器的核心代码进行大量修改,同时也方便进行单元测试,例如可以通过模拟数据源对象来测试视图控制器的功能。