why 如果你的代码块中出现多 if else,往往意味着代码不便于维护,并有必要重构下代码了。本文提供几个小技巧,化解多 if else 的尴尬。
实例 1 1 2 3 4 5 6 7 8 9 var animalConsole = function (type ) { if (type === "fish" ) { console .log("this is fish" ); } else if (type === "bird" ) { console .log("this is bird" ); } }; animalConsole("fish" );
上述代码的问题在于扩展性极差,如果日后想再添加个 cat 就需要再来一个 if else,我们做个调整:
1 2 3 4 5 var animalConsole2 = function (type ) { console .log("this is " + type); }; animalConsole2("fish" );
这样修改之后代码做了简化,但有个问题 console 的文字格式要保持统一,失去了多样性,所以我们进一步调整:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var fish = { console : function ( ) { console .log('我是小鱼儿' ) } } var bird = { console .log('我是鸟人,多多指教' ) } var animalConsole3 = function (animal ) { animal.console() } animalConsole3(fish) animalConsole3(bird)
上述代码使用了多态 ,扩展性变得更好,如果日后想增加个 cat,直接添加一个 cat 对象就可以了,不需要调整 animalConsole3 的代码。但是,也有个小的问题:代码有点松散,一共定义了三个对象。我们进一步调整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var animal = { bird: function ( ) { console .log("我是鸟人哦" ); }, fish: function ( ) { console .log("我是小鱼儿" ); }, cat: function ( ) { console .log("我是可爱喵" ); } }; var animalConsole4 = function (animal, type ) { if (typeof animal[type] === "function" ) { return animal[type](); } }; animalConsole4(animal, "bird" );
上述代码使用了策略模式 ,所有的动物都挂在了 animal 对象上,日后 animal 对象可作为一个配置文件,便于扩展。
但是,上述代码中的 animal 参数有点多余,我们可以利用闭包将其去除:
1 2 3 4 5 6 7 8 9 10 11 var console5 = function (obj ) { return function consoleByType (type ) { if (typeof obj[type] === "function" ) { return obj[type](); } }; }; var animalConsole5 = console5(animal);animalConsole5("bird" ); animalConsole5("fish" );
相较于第一个版本,使用了多态和策略模式的代码就非常便于维护了。
实例 2 下面我们再看一个相对复杂的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function validate (data ) { if (data.username == "" ) { return false ; } if (data.password == "" || data.password.length < 8 ) { return false ; } if (data.description == "" || data.description.length < 20 ) { return false ; } return true ; }
上述是一个数据校验的代码,对上述代码进行重构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 var validator = { hasValue: function (value ) { return typeof value === "string" && value !== "" ; }, maxLength: function (value, max ) { return validator.hasValue(value) && value.length <= max; } }; function Validate ( ) { this .rules = []; } Validate.prototype.setData = function (data ) { this .data = data || {}; }; Validate.prototype.addRules = function (value, ruleType ) { var args = arguments ; ruleType = Array .prototype.splice.call(args, 1 , 1 )[0 ]; rules.push( function ( ) { args[0 ] = this .data[args[0 ]]; return validator[ruleType].apply(null , args); }.bind(this ) ); }; Validate.prototype.vali = function ( ) { for (var i = 0 , len = this .rules.length; i < len; i++) { if (!this .rules[i]()) { return false ; } } return true ; }; var v = new Validate();v.setData({ username: "alex" , password: "helloworld" , description: "nice boy" }); v.addRules("username" , "hasValue" ); v.addRules("password" , "maxLength" , 8 ); v.addRules("descriptoin" , "maxLength" , 20 ); var result = v.vali();
进行重构之后,摒弃了多 if 代码,虽然代码量有所增加,但有利于后期维护。如果需要添加校验规则,则只需要填充 validator 对象和调用 addRules 即可。
总结 去除代码块中繁杂的 if else 逻辑的两个好用的方法:
日后还会补充。