当前位置: 首页 > 编程日记 > 正文

改善代码设计 —— 简化条件表达式(Simplifying Conditional Expressions)

系列博客

1. 改善代码设计 —— 优化函数的构成(Composing Methods)

2. 改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)

3. 改善代码设计 —— 组织好你的数据(Composing Data)

4. 改善代码设计 —— 简化条件表达式(Simplifying Conditional Expressions)

5. 改善代码设计 —— 简化函数调用(Making Method Calls Simpler)

6. 改善代码设计 —— 处理概括关系(Dealing with Generalization)

1. Decompose Conditional (分解条件式)

解释:

"复杂的条件逻辑" 是导致复杂性上升最常见的地方, "条件表达式中堆积的计算过程", "条件式表达得不简洁"等等都是造成复杂的原因. Decompose Conditional 用于将这些复杂的元素从条件表达式中分离出去, 仅在条件表达式中调用简洁的函数.

这样做带来的直接好处是减少重复, 而且代码的可读性提高了.

冲动前:

if (date.After(SUMMER_START) && date.Before(SUMMER_END))
charge
= days * _price + _summerServiceTip;
else
charge
= days * _price;

冲动后:

if (date.IsSummer())
charge
= SummerCharge(days);
else
charge
= WinterCharge(days);

2. Consolidate Conditional Expression (合并条件式)

解释:

如果代码中有一连串的 if 检查语句, 检查语句中的条件不相同, 但最终的行为都是一样的. 对于这样的情况, 应该使用 "逻辑与" 和 "逻辑或" 将它们合并成一个条件表达式, 如果嫌这个合并条件后的表达式太罗嗦, 你还可以将这个表达式提取成一个函数.

冲动前:

if (computer.CPU != "T6670")
return false;
if (computer.RAM != "1.00GB")
return false;
if (computer.SytemType != "32-bit Operating System")
return false;
//other compution

冲动后:

if ((computer.CPU != "T6670") || (computer.RAM != "1.00GB") || (computer.SytemType != "32-bit Operating System"))
return false;
//other compution

你还可以将 if 里长长的条件表达式提取成一个方法, 如 bool IsStandard(Computer computer), 这样在原来的 if 语句中只需要调用这个方法即可微笑

3. Consolidate Duplicate Conditional Fragments (合并重复的条件片段)

解释:

如果条件式的每个分支上都有同样一段代码, 如果这段代码对条件分支在执行这段代码后执行后面的代码没有影响,  请将这段代码移到条件式的外面.

冲动前:

if (date.IsSummer())
{
charge
= days * _price + _summerServiceTip;
PrintDetail();
}
else
{
charge
= days * _price;
PrintDetail();
}
//other compution

冲动后:

charge = days * _price;

if (date.IsSummer())
charge
+= _summerServiceTip;

PrintDetail();
//other compution

4. Remove Control Flag (移除控制标志)

解释:

很多代码里执行一个 for 或者 while 循环用于寻找一个数组里特点的元素, 很多时候在循环开头就执行控制标志的检查, 满足检查条件就继续执行循环查找元素. 如果这一次查找到了想要的元素, 就更改控制标志的值, 让它下次被检查出不符合条件, 从而循环结束.

这并不是一个很好的做法, 使用诸如 break, continue, return 语句会让你的代码意图更加直接, 更加明显.

冲动前:

for (int i = 0; i < suspects.Length; i++)
{
if (!found)
{
if (suspects[i].Name == guessName)
{
sendAlert();
found
= true;
}
}
}

冲动后:

for (int i = 0; i < suspects.Length; i++)
{
if (suspects[i].Name == guessName)
{
sendAlert();
break;
}
}

5. Replace Nested Conditional with Guard Clauses (以卫语句取代嵌套条件式)

解释:

许多程序员觉得函数应该只有一个出口 (return), 结果导致函数中的条件逻辑 (Conditional Logic) 本来完全可以终止下面的代码继续执行 (因为没有必要), 结果却只在函数最后 return, 使人难以看清程序的执行路径.

Replace Nested Conditional with Guard Clauses 用来解决这个问题, 它能带给代码可读性的提高, 还有性能上一点点的优化.

冲动前:

double charge;

if (IsSummer(date))
{
//...
SummerCharge(charge);
}
else
{
//...
WinterCharge(charge);
}

return charge;

冲动后:

double charge;

if (IsSummer(date))
{
//...
SummerCharge(charge);
return charge;
}
else
{
//...
WinterCharge(charge);
return charge;
}

6. Replace Conditional with Polymorphism (以多态取代条件)

解释:

这条重构手法常常用于消除函数中长长的 switch-case 语句. 虽然写一个个的子类比较繁琐, 但随着项目的进行, 好处会体现出来的.

冲动前:

public double Salary(Employee employee)
{
switch(employee.Type):
{
case Employee.Engineer
{
//...
}
case Employee.Salesman:
{
//...
}
//...
default:
{
//...
}
}
}

冲动后:

public abstract double Salary(Employee employee);

class Engineer : Employee
{
public override double Salary(Employee employee)
{
//...
}
}
class Salesman : Employee
{
public override double Salary(Employee employee)
{
//...
}
}

7. Introduce Null Object (引入 Null 对象)

解释:

如果代码中出现很多判断某值是不是为 null , 诸如 if (XXX != null) {//...} else {//...} 这样的情况, 可以考虑使用 Introduce Null Object 重构手段. 这个手段其实并不难以理解, 可以简单理解成为某一个物件在为空状态下设定默认的值域和行为, 可以建立一个子类, 继承父类中需要对 "为空" 情况下做出响应的虚函数或者值域. 它是 Null Object 设计模式里的最基础最常见的手段.

8. Introduce Assertion (引入断言)

解释:

严格上说, 引入断言并不是为了简化条件表达式, 它主要是为了代替条件表达式上面的注释, 通常这样的注释用来解释下面的条件表达式是基于什么样的假设之上的. 通常经过一系列的测试, 发现所写的断言在任何情况下都是正确的, 在系统发布的时候可以把它们全部删除掉.

在 C# 中引入断言使用 Debug.Assert() 方法, 如果一切假设都是正确的, 则代码会顺利的进行.

冲动前:

//index should between 0 to 10
return (customers[index] == "James") ? true : false;

冲动后:

Debug.Assert((index>=0)&&(index <= 10), "Error", "index should between 0 to 10");
return (customers[index] == "James") ? true : false;

如果断言错误, 在运行的时候会有一个消息框给予错误信息的提示.

转载于:https://www.cnblogs.com/waw/archive/2011/10/13/2210618.html

相关文章:

必要时调整应用程序每个辅助进程的线程数

ASP.NET 的请求结构试图在执行请求的线程数和可用资源之间达到一种平衡。已知一个使用足够 CPU 功率的应用程序&#xff0c;该结构将根据可用于请求的 CPU 功率&#xff0c;来决定允许同时执行的请求数。这项技术称作线程门控。但是在某些条件下&#xff0c;线程门控算法不是很…

嵌入式开发「坑」太多?MathWorks 高级工程师教你 debug

文/ 朱雪妍据博思数据发布的《2018-2023年中国嵌入式软件行业市场发展现状调研与投资趋势前景分析报告》表明&#xff1a;2018年上半年我国嵌入式系统软件收入达4240.2亿元&#xff0c;累计增长6.6%&#xff0c;并将持续保持高速增长。嵌入式系统是当前最热门、最具发展前途的I…

[转]cocos2d-js 3.0 屏幕适配方案 分辨率适应

首先介绍一个api和相应的参数&#xff1a; cc.view.setDesignResolutionSize(1024, 768, cc.ResolutionPolicy.FIXED_WIDTH); 这里设置游戏制作的目标尺寸和显示的模式。 模式包括&#xff1a; cc.ResolutionPolicy {// The entire application is visible in the specified a…

两个程序员的泰国普吉岛之行

十一长假后&#xff0c;我和女朋友一起去了普吉岛游玩&#xff08;作为两个程序员&#xff0c;不能每天敲代码&#xff0c;也应该放松下自己&#xff09;&#xff0c;玩的很Happy&#xff0c;也是我们第一次出国&#xff0c;所以更带有许多兴奋。也许是由于玩的太High&#xff…

使用 HttpServerUtility.Transfer 方法在同一应用程序的页面间重定向

采用 Server.Transfer 语法&#xff0c;在页面中使用该方法可避免不必要的客户端重定向。

90行Python代码,让张小龙的微信地球转起来

作者 | xiaorang来源 | 数据分析与统计学之美1.微信地球手机重启后打开微信的一瞬间&#xff0c;会看到一幅有名的图片&#xff0c;上面站着一个张小龙。你可曾想过这样一个问题&#xff0c;如果上面那个地球转起来会是怎样&#xff1f;2.效果图效果简直不要太酷炫&#xff0c;…

70.打印所有Spring boot载入的bean【从零开始学Spring Boot】

【从零开始学习Spirng Boot—常见异常汇总】 问题的提出&#xff1a; 我们在开发过程当中&#xff0c;我们可能会碰到这样的问题&#xff1a;No qualifying bean 就是我们定义的bean无法进行注入&#xff0c;那到底是什么原因呢&#xff0c;有时候挺难定位的&#xff0c;当然这…

了解 C# “.NET研究”4 中的 Dynamic 关键字

dynamic 关键字和动态语言运行时 (DLR) 是 C# 4 和 Microsoft .NET Framework 4 中的重大新增功能。 这些功能在宣布时就引起了人们的极大兴趣&#xff0c;并伴随着许多疑问。 同时人们也给出了很多答案&#xff0c;但这些答案现在已散布于各种文档以及各种技术博客和文章之中。…

“我,懂数据,不怕被裁”:这项核心能力到底有多香?

我见过市面上很多的 Python 讲解教程和书籍&#xff0c;他们大都这样讲 Python 的&#xff1a;先从 Python 的发展历史开始&#xff0c;介绍 Python 的基本语法规则&#xff0c;Python 的 list, dict, tuple 等数据结构&#xff0c;然后再介绍字符串处理和正则表达式&#xff0…

使请求管线内的所有模块尽可能高效

请求管线内的所有模块在每次请求中都有机会被运行。因此&#xff0c;当请求进入和离开模块时快速地触发代码至关重要&#xff0c;特别是在不使用模块功能的代码路径里。分别在使用及不使用模块和配置文件时执行吞吐量测试&#xff0c;对确定这些方法的执行速度非常有用。

PHP smarty缓存

缓存一个页面 test.php <?php//定义该页面缓存文件存放的路径 $filename "../cache/cachetest.html";//定义缓存有效期 $cachetime 5;//判断缓存文件是否存在 if(!file_exists($filename) || filemtime($filename)$cachetime<time()) {//开启内存缓存ob_sta…

在 Visual Basic .NET 或 JScript 代码中使用早期绑定

以往&#xff0c;开发人员喜欢使用 Visual Basic、VBScript 和 JScript 的原因之一就是它们所谓“无类型”的性质。变量不需要显式类型声明&#xff0c;并能够简单地通过使用来创建它们。当从一个类型到另一个类型进行分配时&#xff0c;转换将自动执行。不过&#xff0c;这种便…

Use MVS Dsbame convensions. windows下ftp.exe客户端上传错误

环境:主机 220-FTPD1 IBM FTP CS V1R11 at BT11 windows下的ftp.exe客户端 现象:windows下ftp.exe命令上传文件,报"Use MVS Dsbame convensions." 错误 原因: 主要是IBM FTP Server 文件系统的命名规范造成的: 8个基本字符 解决: 通过 cd 根目录.目录1.目录2----…

算法对建筑业的影响,不仅仅是画图

拿什么来拯救&#xff0c;这些奇葩的设计&#xff1f;奇葩造型位于英国伦敦芬乔奇街 20 号的一座摩天大楼&#xff0c;由于造型像「对讲机」&#xff0c;被取外号「对讲机大楼」。其实造型奇葩倒没什么&#xff0c;也有一些人觉得还挺好看。但问题是&#xff0c;建成之后&#…

如何参与团队合作?

现在&#xff0c;团队合作就是竞争力。随着市场竞争的日益激烈&#xff0c;企业更加强调团队精神&#xff0c;建立群体共识&#xff0c;以达到更高的工作效率。特别是有遇到大型项目时&#xff0c;想凭借一己之力去取得卓越的成果&#xff0c;可能非常困难。想必你也意识到&…

200 个工具分析机器学习十年:开源是大势,工程师是核心

【编者按】人工智能和机器学习经过十年多的发展&#xff0c;在过去的几年间&#xff0c;各类工具数量迎来了持续的爆发式的增长&#xff0c;机器学习也正式由科研走进工业生产阶段。本文作者 —— 来自硅谷一家初创公司的计算机科学家 Chip Huyen 梳理挖掘出 202 个机器学习工具…

将调用密集型的 COM 组件迁移到托管代码

.NET Framework 提供了一个简单的方法与传统的 COM 组件进行交互。其优点是可以在保留现有投资的同时利用新的平台。但是在某些情况下&#xff0c;保留旧组件的性能开销使得将组件迁移到托管代码是值得的。每一情况都是不一样的&#xff0c;决定是否需要迁移组件的最好方法是对…

性能优化工具 MVC Mini Profiler

MVC MiniProfiler是Stack Overflow团队设计的一款对ASP.NET MVC、WebForm 以及WCF 的性能分析的小程序。可以对一个页面本身&#xff0c;及该页面通过直接引用、Ajax、Iframe形式访问的其它页面进行监控,监控内容包括数据库内容&#xff0c;并可以显示数据库访问的SQL&#xff…

刷新UITableView

【from】http://www.superqq.com/blog/2015/08/18/ios-development-refresh-uitableview/ UITableView对于iOS开发者来说一定不会陌生&#xff0c;很有可能你的APP很多界面都用到它。关于UITableView的文章&#xff0c;想必已经不计其数&#xff0c;没事可以多看看。特别是UITa…

算术运算中隐式类型转换

转载于:https://www.cnblogs.com/strider/articles/2220313.html

高文、张钹、杨强隔空论道:AI精度与隐私的博弈

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;AI时代&#xff0c;如何保护大众的隐私&#xff1f;以联邦学习为代表的AI技术能否实现AI协作&#xff0c;提升模型精度的同时&#xff0c;实现数据隐私的保护&#xff1f;中国如何抢占人工智能安全发展的制高点&#x…

避免单线程单元 (STA) COM 组件

默认情况下&#xff0c;ASP.NET 不允许任何 STA COM 组件在页面内运行。若要运行它们&#xff0c;必须在 .aspx 文件内将 ASPCompattrue 属性包含在 Page 指令中。这样就将执行用的线程池切换到 STA 线程池&#xff0c;而且使 HttpContext 和其他内置对象可用于 COM 对象。前者…

将 SQL Server 存储过程用于数据访问

在 .NET Framework 提供的所有数据访问方法中&#xff0c;基于 SQL Server 的数据访问是生成高性能、可缩放 Web 应用程序的推荐选择。使用托管 SQL Server 提供程序时&#xff0c;可通过使用编译的存储过程而不是特殊查询获得额外的性能提高。

centos下安装apache + subversion(转)

目录&#xff1a; 一.安装apr跟apr-util 二.安装apache服务器 三. 安装subversion 四. 配置subversion 五. 配置apache的httpd.conf 六. 验证安装 七.导入数据到资料库八.版本库服务器的同步&#xff08;新加入的&#xff09; 附&#xff1a;安装过程中遇到的问题 一.安装apr、…

真香!3个月0基础转型大厂数据分析师,他做对了什么?

年初的黑天鹅打乱了我的求职阵脚&#xff0c;专业不对口&#xff0c;无实习经验&#xff0c;在求职路上的竞争优势几乎为0&#xff0c;然而&#xff0c;开启自救模式后&#xff0c;我顺利成为了头条数据分析师&#xff0c;下面我就讲讲人生是怎么开挂的。随着人工智能普及&…

OpenStack快速入门

OpenStack云计算快速入门&#xff08;1&#xff09;该教程基于Ubuntu12.04版&#xff0c;它将帮助读者建立起一份OpenStack最小化安装。我是五岳之巅&#xff0c;翻译中多采用意译法&#xff0c;所以个别词与原版有出入&#xff0c;请大家谅解。我不是英语专业&#xff0c;我觉…

将 SqlDataReader 类用于快速只进数据游标

SqlDataReader 类提供了一种读取从 SQL Server 数据库检索的只进数据流的方法。如果当创建 ASP.NET 应用程序时出现允许您使用它的情况&#xff0c;则 SqlDataReader 类提供比 DataSet 类更高的性能。情况之所以这样&#xff0c;是因为 SqlDataReader 使用 SQL Server 的本机网…

微软小冰从上海音乐学院音工系毕业,师从于阳、陈世哲

6月29日&#xff0c;经上海音乐学院音乐工程系评定&#xff0c;人工智能微软小冰和她的人类同学——上音音乐工程系音乐科技专业毕业生一起毕业&#xff0c;并授予微软小冰上海音乐学院音乐工程系2020届“荣誉毕业生”称号。微软小冰和上海音乐学院的毕业生们一起参加了于6月29…

Typedef用法学习

不管实在C还是C代码中&#xff0c;typedef这个词都不少见&#xff0c;当然出现频率较高的还是在C代码中。typedef与#define有些相似&#xff0c;但更多的是不同&#xff0c;特别是在一些复杂的用法上&#xff0c;就完全不同了&#xff0c;看了网上一些C/C的学习者的博客&#x…

开发板tftp:timeout问题

想要从PC上面tftp文件的时候遇到了tftp:timeout的问题&#xff1a; >: tftp -gr gprsapp 192.168.1.38tftp: timeout 检查了网络&#xff0c;可以ping的通PC。PC的tftp服务器也已经打开了&#xff0c;测试从开发板上面向PC上tftp传送数据也是可以的&#xff1a;说明开发板上…