这个问题想了好长时间,自己平常写代码也会出现很多if嵌套问题,也没有很好的处理,感觉代码不好看,在网上查资料总结了下,常见if else判断 出现在逻辑异常判断和 各种不同状态处理
常见异常例子
逻辑异常是一个正常的业务流程,状态管理也是一个正常的业务流程, 举个例子
逻辑异常
// 逻辑异常
function addUser(user: any){
if(user.name ==null){
//do what
}
if(user.phone == null){
// do other what
}
}
状态处理
// 状态处理
funtion applyUser(){
if (user.status == 1){
// do what
}
if ( user.status == 2){
// do what;
}
}
常见就这2种,夹杂在一起,这些代码都是必须的,所以会给人无从下手的感觉
逻辑异常解决办法
1. 合并条件(A:熟知语言常if判断为false的条件,B:常用 或条件);
function addUser(user){
// 重构前
if(user.name == null || user == ''){
return false'
}
if(user.name == null){
return false
}
// 合并后,(js中,null,undefined, '',0 在 if中都表示 false,其他语言类似特征可以参考这个)
if(!user.name){
return false;
}
// 重构前
if(user.age < 18)
return false;
if(user.age > 60)
return false;
if(!user.name)
return false;
// 重构后
if(user.age < 18 || user.age > 60 || !user.name){
return false;
}
总结: 如果有一系列条件测试都得到相同结果,将这些结果测试合并为一个条件表达式。
2 少用 result 临时变量,直接return, 如果if-else没有嵌套关系,,提到第一层
getMoney(user){
let result;
if(user.type == 'isChild') {
result = do1();
}else{
if(user.type == 'oldman'){
result = do2();
}
else{
if(user.type == 'qingnian'){
result = do3();
else{
result = do4();
}
}
}
return result;
}
// 重构后
getMoney(user){
if(user.type == 'isChild') {
return do1();
};
if(user.type == 'oldman'){
return do2();
};
if(user.type == 'qingnian'){
return do3();
};
return do4();
}
3. 把正常的业务流程放到最外面
public double getAdjustedCapital(){
double result = 0.0;
if(_capital > 0.0 ){
if(_intRate > 0 && _duration >0){
resutl = (_income / _duration) *ADJ_FACTOR;
}
}
return result;
}
#### A:,减少嵌套和移除临时变量:
public double getAdjustedCapital(){
if(_capital <= 0.0 ){
return 0.0;
}
if(_intRate > 0 && _duration >0){
return (_income / _duration) *ADJ_FACTOR;
}
return 0.0;
}
#### B:在优化一把,把主要逻辑放到外面
public double getAdjustedCapital(){
if(_capital <= 0.0 ){
return 0.0;
}
if(_intRate <= 0 || _duration <= 0){
return 0.0;
}
return (_income / _duration) *ADJ_FACTOR;
}
总结: 将条件反转使异常情况先退出,让正常流程维持在主干流程。
在举个例子,看个比较复杂的,多层嵌套
public ArrayList<Student> getStudents(int uid){
ArrayList<Student> result = new ArrayList<Student>();
Student stu = getStudentByUid(uid);
if (stu != null) {
Teacher teacher = stu.getTeacher();
if(teacher != null){
ArrayList<Student> students = teacher.getStudents();
if(students != null){
for(Student student : students){
if(student.getAge() > = 18 && student.getGender() == MALE){
result.add(student);
}
}
}else {
logger.error("获取学生列表失败");
}
}else {
logger.error("获取老师信息失败");
}
} else {
logger.error("获取学生信息失败");
}
return result;
}
// 优化一把
public ArrayList<Student> getStudents(int uid){
ArrayList<Student> result = new ArrayList<Student>();
Student stu = getStudentByUid(uid);
if (stu == null) {
logger.error("获取学生信息失败");
return result;
}
Teacher teacher = stu.getTeacher();
if(teacher == null){
logger.error("获取老师信息失败");
return result;
}
ArrayList<Student> students = teacher.getStudents();
if(students == null){
logger.error("获取学生列表失败");
return result;
}
for(Student student : students){
if(student.getAge() > 18 && student.getGender() == MALE){
result.add(student);
}
}
return result;
}
状态管理
1.代码中另外一种常见的if else是根据 状态返回不同业务, 如何状态处理具有公共性,这样的话我们可以把状态处理抽成一个公共的方法,
function addUser(user){
if(user.status == "isChild"){
let flg = user.getMony;
user.money = flg* user.xxxx
} else if(user.status == "old"){
let flg = user.getMony;
user.money = flg* user.xxxx
}
// 把处理公共的抽成一个方法
function getMoney(user){ return money};
function allMoney (user){
if(user.status == "isChild"){
return getMoney(user);
} else if(user.status == "old"){
ureturn getMoney(user);
}
}
2.要是很复杂的就可以用面向对象的玩法,写个抽象类,每个具体的实现这个抽象类,就不存在if else(其实面向对象的打法,基本可以做到不用if else )
public getSpeed(){
switch(_type){
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed()-getLoadFactor()*_numberOfCoconuts;
case NORWEGIAN_BLUE:
return (_isNailed)?0:getBaseSpeed(_voltage);
}
}
// 重构一把
class Bird{
abstract double getSpeed();
}
class European extends Bird{
double getSpeed(){
return getBaseSpeed();
}
}
class African extends Bird{
double getSpeed(){
return getBaseSpeed()-getLoadFactor()*_numberOfCoconuts;
}
}
class NorwegianBlue extends Bird{
double getSpeed(){
return (_isNailed)?0:getBaseSpeed(_voltage);
}
这种打法伤筋动骨,一般用的少
以上就是自己体会,和从网上查找资料的一些总结,自己能学习学习,也希望能帮助到大家