改善代码设计 —— 简化“.NET技术”条件表达式(Simplifying Conditional Expressions)

简介:   系列博客      1. 改善代码设计 —— 优化函数的构成(Composing Methods)      2. 改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)      3.

  系列博客

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

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

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

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

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

      6. 上海企业网站设计与制作f="http://kb.cnblogs.com/page/101133/">改善代码设计 —— 处理概括关系(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;

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

目录
相关文章
|
10月前
|
监控 Cloud Native 测试技术
.NET技术深度解析:现代企业级开发指南
每日激励:“不要一直责怪过去的自己,他曾经站在雾里也很迷茫”。我是蒋星熠Jaxonic,一名在代码宇宙中探索的极客旅人。从.NET Framework到.NET 8,我深耕跨平台、高性能、云原生开发,践行领域驱动设计与微服务架构,用代码书写技术诗篇。分享架构演进、性能优化与AI融合前沿,助力开发者在二进制星河中逐光前行。关注我,共探技术无限可能!
.NET技术深度解析:现代企业级开发指南
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
684 0
|
开发框架 算法 .NET
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
347 6
|
开发框架 Cloud Native .NET
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
389 6
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
527 3
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
980 0
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
836 5
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
499 7
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
418 0
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
443 0