[关闭]
@hucheng91 2017-10-09T16:43:45.000000Z 字数 3690 阅读 687

多层if嵌套问题

这个问题想了好长时间,自己平常写代码也会出现很多if嵌套问题,也没有很好的处理,感觉代码不好看,在网上查资料总结了下,常见if else判断 出现在逻辑异常判断和 各种不同状态处理(上次晓艺那段代码 就是不同状态处理,具体代码没找到),逻辑异常是一个正常的业务流程,状态管理也是一个正常的业务流程, 举个例子

  1. // 逻辑异常
  2. function addUser(user: any){
  3. if(user.name ==null){
  4. //do what
  5. }
  6. if(user.phone == null){
  7. // do other what
  8. }
  9. }
  10. // 状态处理
  11. funtion applyUser(){
  12. if (user.status == 1){
  13. // do what
  14. }
  15. if ( user.status == 2){
  16. // do what;
  17. }
  18. }

常见就这2种,夹杂在一起,这些代码都是必须的,所以会给人无从下手的感觉

逻辑异常解决办法

  1. 合并条件(A:熟知语言常if判断为false的条件,B:常用 或条件);

    1. function addUser(user){
    2. // 重构前
    3. if(user.name == null || user == ''){
    4. return false'
    5. }
    6. if(user.name == null){
    7. return false
    8. }
    9. // 合并后,(js中,null,undefined, '',0 在 if中都表示 false,其他语言类似特征可以参考这个)
    10. if(!user.name){
    11. return false;
    12. }
    13. // 重构前
    14. if(user.age < 18)
    15. return false;
    16. if(user.age > 60)
    17. return false;
    18. if(!user.name)
    19. return false;
    20. // 重构后
    21. if(user.age < 18 || user.age > 60 || !user.name){
    22. return false;
    23. }

    总结: 如果有一系列条件测试都得到相同结果,将这些结果测试合并为一个条件表达式。
    2 少用 result 临时变量,直接return, 如果if-else没有嵌套关系,,提到第一层

    1. getMoney(user){
    2. let result;
    3. if(user.type == 'isChild') {
    4. result = do1();
    5. }else{
    6. if(user.type == 'oldman'){
    7. result = do2();
    8. }
    9. else{
    10. if(user.type == 'qingnian'){
    11. result = do3();
    12. else{
    13. result = do4();
    14. }
    15. }
    16. }
    17. return result;
    18. }
    19. // 重构后
    20. getMoney(user){
    21. if(user.type == 'isChild') {
    22. return do1();
    23. };
    24. if(user.type == 'oldman'){
    25. return do2();
    26. };
    27. if(user.type == 'qingnian'){
    28. return do3();
    29. };
    30. return do4();
    31. }
  2. 把正常的业务流程放到最外面

    1. public double getAdjustedCapital(){
    2. double result = 0.0;
    3. if(_capital > 0.0 ){
    4. if(_intRate > 0 && _duration >0){
    5. resutl = (_income / _duration) *ADJ_FACTOR;
    6. }
    7. }
    8. return result;
    9. }
    10. A:,减少嵌套和移除临时变量:
    11. public double getAdjustedCapital(){
    12. if(_capital <= 0.0 ){
    13. return 0.0;
    14. }
    15. if(_intRate > 0 && _duration >0){
    16. return (_income / _duration) *ADJ_FACTOR;
    17. }
    18. return 0.0;
    19. }
    20. B:在优化一把,把主要逻辑放到外面
    21. public double getAdjustedCapital(){
    22. if(_capital <= 0.0 ){
    23. return 0.0;
    24. }
    25. if(_intRate <= 0 || _duration <= 0){
    26. return 0.0;
    27. }
    28. return (_income / _duration) *ADJ_FACTOR;
    29. }

    总结: 将条件反转使异常情况先退出,让正常流程维持在主干流程。

在举个例子,看个比较复杂的,多层嵌套

  1. public ArrayList<Student> getStudents(int uid){
  2. ArrayList<Student> result = new ArrayList<Student>();
  3. Student stu = getStudentByUid(uid);
  4. if (stu != null) {
  5. Teacher teacher = stu.getTeacher();
  6. if(teacher != null){
  7. ArrayList<Student> students = teacher.getStudents();
  8. if(students != null){
  9. for(Student student : students){
  10. if(student.getAge() > = 18 && student.getGender() == MALE){
  11. result.add(student);
  12. }
  13. }
  14. }else {
  15. logger.error("获取学生列表失败");
  16. }
  17. }else {
  18. logger.error("获取老师信息失败");
  19. }
  20. } else {
  21. logger.error("获取学生信息失败");
  22. }
  23. return result;
  24. }
  25. // 优化一把
  26. public ArrayList<Student> getStudents(int uid){
  27. ArrayList<Student> result = new ArrayList<Student>();
  28. Student stu = getStudentByUid(uid);
  29. if (stu == null) {
  30. logger.error("获取学生信息失败");
  31. return result;
  32. }
  33. Teacher teacher = stu.getTeacher();
  34. if(teacher == null){
  35. logger.error("获取老师信息失败");
  36. return result;
  37. }
  38. ArrayList<Student> students = teacher.getStudents();
  39. if(students == null){
  40. logger.error("获取学生列表失败");
  41. return result;
  42. }
  43. for(Student student : students){
  44. if(student.getAge() > 18 && student.getGender() == MALE){
  45. result.add(student);
  46. }
  47. }
  48. return result;
  49. }

状态管理

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 )

  1. public getSpeed(){
  2. switch(_type){
  3. case EUROPEAN:
  4. return getBaseSpeed();
  5. case AFRICAN:
  6. return getBaseSpeed()-getLoadFactor()*_numberOfCoconuts;
  7. case NORWEGIAN_BLUE:
  8. return (_isNailed)?0:getBaseSpeed(_voltage);
  9. }
  10. }
  11. // 重构一把
  12. class Bird{
  13. abstract double getSpeed();
  14. }
  15. class European extends Bird{
  16. double getSpeed(){
  17. return getBaseSpeed();
  18. }
  19. }
  20. class African extends Bird{
  21. double getSpeed(){
  22. return getBaseSpeed()-getLoadFactor()*_numberOfCoconuts;
  23. }
  24. }
  25. class NorwegianBlue extends Bird{
  26. double getSpeed(){
  27. return (_isNailed)?0:getBaseSpeed(_voltage);
  28. }

这种打法伤筋动骨,一般用的少

以上就是自己体会,和从网上查找资料的一些总结,自己能学习学习,也希望能帮助到大家

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注