刚看到一个提问帖: 《如果程序中出现多层嵌套的 if...else...语句,如何重构可使程序逻辑变得更为清晰易读?》,因回答篇幅比较大,单独开个帖子答一下。

个人喜好代码风格不一样,下面只是我认为好的代码风格,不喜勿喷。如果有其他好的技巧,欢迎分享补充。

技巧一#

删除 else

如:

function test($arg)
{
if($arg == 'foobar'){
return true;
}else{
return false;
}
}

尽量写成这样

function test($arg)
{
if($arg == 'foobar'){
return true;
} return false;
}

优先将代码量少,可使流程中断的代码块(return, throw excetion, continue ...)放到 if 中, 提前中断代码。

技巧二#

拆分为多个函数

如果整个 if else 中的代码比较多,或者 if 与 else 中带代码不会导致后面的判断流程中断,并且还有 if else 之外的代码,将就 if else 中的代码拆分为多个函数。

if($age > 18){
doSomeThingA();
doSomeThingB();
doSomeThingC();
}else{
doSomeThingD();
doSomeThingE();
}

这种方式需要将函数名取的尽量清晰易懂,不要嫌长。

技巧三#

罗列规则式的写代码

多层 if 嵌套的语法,把他写成线性的,就像写规则一样将其一条条罗列出来

如:

function match($age, $salary, $pretty){
if($age > 18){
// do some thing A;
if($salary > 5000){
// do some thing B;
if($pretty == true){
return true;
}
}
} return false;
}

改写成这样是不是清晰多了?

function match($age, $salary, $pretty){
if($age < 18){
return false;
} // do some thing A; if($salary < 5000){
return false;
} // do some thing B; return $pretty == true;
}

总结#

少用 else , 提前中断(return)!!!#

少用 else , 提前中断(return)!!!#

少用 else , 提前中断(return)!!!#

重要的事情说三遍!

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

我也来尝试回答这个问题如果程序中出现多层嵌套的 if...else...语句,如何重构可使程序逻辑变得更为清晰易读?

一般原则是if 是越少越好,能不用就不用,层级越少越好。

技巧1:映射表法#

function contry_initial($country){
if ($country==="China" ){
return "CHN";
}else if($country==="America"){
return "USA";
}else if($country==="Japna"){
return "JPN";
}else{
return "OTHER";
}
}

这样的if语句,可以看到值和返回是一一对应的,所以你可以这样写

function contry_initial($country){
$countryList=[
"China"=> "CHN",
"America"=> "USA",
"Japna"=> "JPN",
]; if(in_array($country, array_keys($countryList))) {
return $countryList[$country];
}
return "Other"; }

如果需要更加自由的定义映射表的话,可以这样写

function contry_initial($country, array $countryList){
if(in_array($country, array_keys($countryList))) {
return $countryList[$country];
}
return "Other";
}

完全去掉if语句可以写成

function contry_initial($country, array $countryList){
return in_array($country, array_keys($countryList))?$countryList[$country]:"Other";
}

技巧二:多维映射表#

自己制定一个标准,建立一个多维的映射表,然后尽量少的if语句去囊括所有范例

function match($age,$gender,$pretty){
$list=[
['age'=>[1,12], 'gender'=>"Male",'pretty'=>true,'action'=>function(){//do something},'return'=>'pretty young man'],
['age'=>[1,12], 'gender'=>"Female",'pretty'=>true,'action'=>function(){//do something},'return'=>'pretty young lady'],
['age'=>[1,12], 'gender'=>"Male", 'pretty'=>false,'action'=>function(){//do something},'return'=>'boy'],
['age'=>[1,12], 'gender'=>"Female",'pretty'=>false,'action'=>function(){//do something},'return'=>'girl'],
['age'=>[13,18], 'gender'=>"Male", 'pretty'=>true,'action'=>function(){//do something},'return'=>'pretty man'],
....
]; foreach($list as $item){
if($age>=$item['age'][0]&&$age<=$item['age'][1]&&$gender===$item['gender']&&$pretty===$item['pretty']){
$item['action']();
return $item['return']; }
}
return null; }

当然,这样排列组合可能会有很多案例,而callable的代码也会有重复。所以改进的方案是

function match($age,$gender,$pretty){
$ageList=[
[ "age"=>[1,12],"action"=>function(){},"return"=>"young"],
[ "age"=>[13,18],"action"=>function(){},"return"=>"teenage"],
[ "age"=>[19,100],"action"=>function(){},"return"=>"adult"],
[ "age"=>[100,1000],"action"=>function(){},"return"=>"adult"],
]; $genderList=[
'Male'=>["action"=>function(){},"return"=>"man"],
'Female'=>["action"=>function(){},"return"=>"lady"],
'default'=>["action"=>function(){},"return"=>"person"],
]; $prettyList=[
true=>["action"=>function(){},"return"=>"pretty"],
false=>["action"=>function(){},"return"=>""],
]; foreach($ageList as $item){
if($age>=$item['age'][0]&&$age<=$item['age'][1]){
$item['action']();
$returnValue= $item['return'];
}
} if(in_array($gender,array_keys($genderList))) {
$genderList[$gender]['action']();
$returnValue .=" ".$genderList[$gender]['return'];
} else {
$genderList['default']['action']();
$returnValue .=" ".$genderList['default']['return'];
} $prettyList[$pretty]['action'](); return $prettyList[$pretty]['return']." ".$returnValue;
}

总结#

以上代码并不完美,总之要更具需要去重构,而不是为了优雅而重构。

使用映射表法的好处是提高单元测试的覆盖率,而坏处是增加了加载时间和消耗内存空间

当然,还是要注意一些

  • return能越早越好
  • if else 语句越少越好,可以用condition?a:b 表达的,就不要用if else
  • 有一一对应关系的,使用映射表。

改善过多的if else的更多相关文章

  1. MySQL监控模板说明-Percona MySQL Monitoring Template for Cacti

    http://blog.chinaunix.net/uid-16844903-id-3535535.html https://www.percona.com/doc/percona-monitorin ...

  2. Percona监控MySQL模板详解

    InnoDB Adaptive Hash Index 显示了"自适应哈希索引"的使用情况,哈希索引只能用来搜索等值的查询. # Hash table size 17700827, ...

  3. 编写高质量代码改善C#程序的157个建议——建议78:应避免线程数量过多

    建议78:应避免线程数量过多 在多数情况下,创建过多的线程意味着应用程序的架构设计可能存在着缺陷.经常有人会问,一个应用程序中到底含有多少线程才是合理的.现在我们找一台PC机,打开Windows的任务 ...

  4. [转]响应式WEB设计学习(3)—如何改善移动设备网页的性能

    原文地址:http://www.jb51.net/web/70362.html 前言 移动设备由于受到带宽.处理器运算速度的限制,因而对网页的性能有更高的要求.究竟是网页中的何种元素拉低了网页在移动设 ...

  5. 改善C#公共程序类库质量的10种方法

    最近重构一套代码,运用以下几种方法,供参考. 1  公共方法尽可能的使用缓存 public static List<string> GetRegisteredCompany() { Str ...

  6. 编写高质量代码--改善python程序的建议(六)

    原文发表在我的博客主页,转载请注明出处! 建议二十八:区别对待可变对象和不可变对象 python中一切皆对象,每一个对象都有一个唯一的标识符(id()).类型(type())以及值,对象根据其值能否修 ...

  7. 重构HTML改善web应用设计

    本文从良构,有效性,布局三个角度,结合往日项目开发经历, 整理总结重构HTML改善Web应用设计的几点规则和做法.部分参考自<重构HTML改善Web应用设计>. 重构.什么是重构?为什么要 ...

  8. Microsoft.VisualBasic.dll的妙用and 改善C#公共程序类库质量的10种方法

    Microsoft.VisualBasic.dll的妙用(开发中肯定会用到哦) 前言 做过VB开发的都知道,有一些VB里面的好的函数在.NET里面都没有,而Microsoft.VisualBasic. ...

  9. 改善C#公共程序类库质量的10种方法和工具

    最近重构一套代码,运用以下几种方法,供参考. 1  公共方法尽可能的使用缓存 public static List<string> GetRegisteredCompany() { Str ...

随机推荐

  1. 针对ajax执行后swiper特效无法执行解决方案

    ajax执行后重新绑定swiper事件.

  2. [LeetCode]题解(python):113 Path Sum II

    题目来源 https://leetcode.com/problems/path-sum-ii/ Given a binary tree and a sum, find all root-to-leaf ...

  3. linux常用经典命令

    1.查看cpu # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数   # 查看物理CPU个数 #物理cpu个数 ...

  4. KingBlog记录

    本片文章其他人可能看不懂,只是我做记录用,不要见怪 KingBlogCMS总结 开发工具: VS2012+SOLServer2008+IIS 开发语言: ASP.NET.Html.js.JQ 第三方: ...

  5. JQuery兼容IE6问题汇总(不断更新)

    兼容IE6真是苦逼的差事,无奈中... 逗号的问题:IE6中要去掉最后的逗号 var o={ id:1, Name:"abc", //这里的逗号一定要去掉 } HTML的结构,由于 ...

  6. 白话LINQ系列1---什么是LINQ?

    一.本系列目标 1.理解LINQ: 2.能写得复杂的LINQ语句(比如:动态查询): 3.理解表达式树及相关概念: 4.熟练运用LINQ写出优美的代码(希望一起努力,最终达到): 二.LINQ为何物? ...

  7. 【转】PowerShell入门(二):PowerShell是Cmd命令行的加强版吗?

    转至:http://www.cnblogs.com/ceachy/archive/2013/01/31/PowerShell_vs_Cmd.html PowerShell是命令行的加强版吗?Power ...

  8. Android安装失败 Installation error code: -110

    在系统开发过程中,开发的app管理器,发现怎么安装都是失败. 详细的查看了log发现. I/ActivityManager(  899): START {dat=file:///mnt/sdcard/ ...

  9. 获取token,绑定微信号,自定义菜单,事件响应demo

    摘要: 这个demo包含了获取token,绑定微信号,设置自定义菜单,响应文本和事件 这个教程的基础篇和提升篇都看完了,总感觉有点隔靴挠痒的感觉,讲的东西我都懂,没有吸收多少新鲜的知识.貌似还没有我这 ...

  10. [转]使用xcode4 workspace 多个project协同工作

    转载地址:http://erlangprogram.com/use-xcode4-workspace   一般的某个应用单独新建一个 project 就可以了,然后把所有的程序文件都放在里面,这个可以 ...