概述
使用 if - else 的两种常见场景:
// 1.非空异常判断
id object;
if (object == nil) {
// code
} else {
// code
}
// 2.值状态判断
if ([object isMemberOfClass:[NSObject class]]) {
// code
} else {
// code
}
对于第一种情况,可采取的优化方式有
- 合并条件表达式
- 减少嵌套
- 移除临时变量等
原则是尽可能地维持正常流程代码在最外层,异常判断最先判断。
对于第二种情况
- 可以将每个状态对应的代码段封装成一个方法,这样代码可以更清晰
- 使用多态替代 if - else 代码段
值得注意的是,对于第一种使用 if-else 的情况,可以多多优化,但对于第二种情况,要慎重使用,不能为了优化而优化。
非空异常判断 if - else 代码段的优化
1.合并表达式,使代码更清晰易懂
int number = 100;
// 优化前
if (number > 10) {
return nil;
}
if (number < -10) {
return nil;
}
if (number == 5) {
return nil;
}
// 使用合并表达式条件优化后
if (number > 10 || number < -10 || number == 5) {
return nil;
}
2.减少 if - else 嵌套,将包含关系改为平行关系,避免逻辑嵌套太深,使代码逻辑清晰明了,一目了然。
int money = 6;
// 优化前
if (money < 0) {
return @"食不果腹,衣不蔽体";
} else if (money > 100) {
return @"财务自由";
} else if (money > 10) {
return @"小康家庭";
} else if (money > 5) {
return @"温饱不愁";
} else {
return @"贫困家庭";
}
// 优化后
if (money < 0) {
return @"食不果腹,衣不蔽体";
}
if (money > 100) {
return @"财务自由";
}
if (money > 10) {
return @"小康家庭";
}
if (money > 5) {
return @"温饱不愁";
}
return @"贫困家庭";
3.将异常判断放在最前面,且尽量减少临时变量改用return直接返回,使代码逻辑清晰。
int number = 10;
BOOL flag = NO;
BOOL otherFlag = NO;
// 优化前
if (number > 10) {
return nil;
}
if (otherFlag) {
int result = 0;
if (flag) {
result = number * 2;
} else {
result = number *-2;
}
return result;
}
return nil;
// 将上面的异常判断放在最前面,且较少临时变量的使用, 再合并表达式且将判断改为平行关系。异常条件先退出这一条可适用于请求网络数据后,对网络数据进行判断格式检查时,先将异常情况的处理放在最前面。
if (number > 10 && !otherFlag) {
return nil;
}
if (flag) {
return number * 2;
}
return number *-2;
值状态 if-else 的优化
1.将每种状态下的长段代码提取成一个函数
int number = 10;
// 优化前
if (number > 10) {
// code balabala...
} else {
// code balabala...
}
// 优化前
if (number > 10) {
[self funationA];
} else {
[self funationB];
}
2.使用多态替代 if-else
以上阐述其他的优化方式只能优化 if-else 代码段结构,但使用多态可以替代 if-else 。
这里使用多态 + map + 反射具体实现,当然还有其他几种实现方式,比如策略模式 + 工厂模式,不过我认为这种实现方式过于庞大。
举例来说,现在有个业务需求:根据汽车品牌,获取汽车配置。
使用 if-else 实现需求
NSString *carBrand = @"BMW";
if ([carBrand isEqualToString:@"BMW"]) {
// BMW Configuration
} else if ([carBrand isEqualToString:@"Benz"]) {
// Benz Configuration
}
使用多态 + map + 反射实现
//1. 声明汽车抽象类
@interface Car : NSObject
// 这个方法也可以提取到一个protocol中
- (NSString *)configuration;
@end
//2. 声明具体的汽车子类,并实现其相应方法
//2.1 声明 BenzCar 类
@interface BenzCar : Car
@end
@implementation BenzCar
- (NSString *)configuration {
return @"BenzCar configuration";
}
@end
//2.2 声明 BMWCar 类
@interface BMWCar : Car
@end
@implementation BMWCar
- (NSString *)configuration {
return @"BMWCar configuration";
}
@end
//3. 实现使用map + 反射机制的依托类
// 3.1 类的声明
@interface CarConfigurationHelper : NSObject
+ (NSString *)carConfigurationWithCarBrand:(NSString *)brand;
@end
// 3.2 类的实现
@implementation CarConfigurationHelper
+ (NSString *)carConfigurationWithCarBrand:(NSString *)brand {
static NSDictionary *map = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
map = @{
@"Benz" : [BenzCar class],
@"BMW" : [BMWCar class]
};
});
if (!map[brand]) {
return nil;
}
Car *car = [[map[brand] alloc] init];
return [car configuration];
}
@end
//4.客户端的使用
- (void)function {
NSString *configuration = [CarConfigurationHelper carConfigurationWithCarBrand:@"BMW"];
NSLog(@"Car configuration: %@",configuration);
}
参考:《重构_改善既有代码的设计》