七、重构4:使用以查询取代临时变量再次对Statement()方法进行重构

1. 经过了之前几篇文章的重构后,Customer中的statement()方法的具体代码,如下图所示。在计算每部电影的金额和积分时,我们调用的是Rental类的对象的相应的方法。下图中的方法与充电项计费项目的原始代码中的方法相比可谓是简洁了许多,而且易于理解与维护。

2.不过上面的代码仍然有重构的空间,举个例子,如果我们要将结果以HTML的形式进行组织的话,我们需要将上面的代码进行复制,然后修改result变量的文本组织方式即可。这可能就是程序员经常做的事情Ctrl+C、Ctrl+V,很多程序员是这样来修改代码的,这种修改代码快速,功能实现方便,但是这样的修改代码会给我们的系统遗留很多无用的代码。使用Ctrl+C、Ctrl+V这种非常方便的方式来修改代码,会造成方法中的好多临时变量都被复制一份,这是完全相同的,这样就容易产生重复的代码。在这种情况下,我们需要使用“Replace Temp with Query”(已查询取代临时变量)的重构手法来取出上图所示的红框中的临时变量。

上图中红框所框出来的每个临时变量我们都会提取出一个查询方法,下图中所示的代码,就是使用“Replace Temp with Query”(已查询取代临时变量)规则重构后的Statement()方法,以及提取的两个查询函数。

3.经过上面这些步骤的重构,Customer类的具体代码如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace LeasePowerBank
{ /// <summary>
/// 客户类
/// </summary>
public class Customer
{ string Name;//用户名称
public List<Rental> listRentals=new List<Rental>();//用户租赁的充电宝
public Customer(string name)
{ Name = name;
} public void AddRental(Rental rental)
{ listRentals.Add(rental);
} public string Statement()
{ string result = $"{Name} 的租赁账单:\n"; result += $"总金额为:{GetTotalAmount()}\n";
result += $"你本次获得了:{GetTotalFrequentRenterPoints()}积分 ";
return result; } /// <summary>
/// 计算总金额
/// </summary>
private decimal GetTotalAmount()
{ decimal totalAmount = 0M; //总金额
foreach (var item in listRentals)
{ totalAmount+= item.GetAmount();//总价计算 } return totalAmount; } /// <summary>
/// 计算积分
/// </summary>
private decimal GetTotalFrequentRenterPoints()
{
int frequentRenterPoints = 0; //用户积分 foreach (var item in listRentals)
{
frequentRenterPoints += item.GetFrequentRenterPoints();//计算积分
} return frequentRenterPoints;
}
}
}
 
4. 我们的测试用例依然不变。在每次重构后我们都需要调用上述的测试用例来检查重构是否产生了副作用。现在我们的类间的依赖关系没怎么发生变化,只是相应类中的方法有些变化。在Visual Studio 2019的菜单栏上找到“测试-->运行所有测试”菜单项。或者在“测试资源管理器中”选择 “在视图中运行所有测试”按钮, 运行测试用例。监测重构的结果是否正确。如下图。

代码重构与单元测试——使用“以查询取代临时变量”再次对Statement()方法进行重构(七)的更多相关文章

  1. 《重构-改善既有代码的设计》学习笔记---Replace Temp with Query(以查询取代临时变量)

    临时变量的问题在于: 它们是暂时的,而且只能在所属函数内使用.由于临时变量只在所属函数内可见,所以,如果很多地方都在用这个临时变量,就会驱使你写出更长的函数.如果把临时变量替换为一个查询,那么其他函数 ...

  2. 重构改善既有代码设计--重构手法04:Replace Temp with Query (以查询取代临时变量)

    所谓的以查询取代临时变量:就是当你的程序以一个临时变量保存某一个表达式的运算效果.将这个表达式提炼到一个独立函数中.将这个临时变量的所有引用点替换为对新函数的调用.此后,新函数就可以被其他函数调用. ...

  3. 重构手法之Replace Temp with Query(以查询取代临时变量)

    返回总目录 6.4Replace Temp with Query(以查询取代临时变量) 概要 你的程序以一个临时变量保存某一表达式的运算结果. 将这个表达式提炼到一个独立函数中.将这个临时变量的所有引 ...

  4. 重构改善既有代码设计--重构手法06:Split Temporary Variable (分解临时变量)

    你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果.针对每次赋值,创造一个独立.对应的临时变量 double temp = 2 * (_height + _width); ...

  5. 重构改善既有代码设计--重构手法02:Inline Method (内联函数)& 03: Inline Temp(内联临时变量)

    Inline Method (内联函数) 一个函数调用的本体与名称同样清楚易懂.在函数调用点插入函数体,然后移除该函数. int GetRating() { return MoreThanfiveLa ...

  6. 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码

    建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...

  7. 重构手法之Split Temporary Variable(分解临时变量)

    返回总目录 本小节目录 Split Temporary Variable(分解临时变量) Remove Assignments to Parameters(移除对参数的赋值) 6.6Split Tem ...

  8. 第1章 重构,第一个案例(1):糟糕的statement函数设计

    1. 启航:影片出租,计算每一位顾客的消费金额并打印清单 1.1 场景说明: (1)影片分类规则:普通片.儿童片和新片等3类 (2)每种影片计算租金的方式. ①普通片:基本租金为2元,超过2天的部分每 ...

  9. 删除ecshop底部共执行个查询Gzip 已禁用,占用内存方法

    删除ecshop底部共执行个查询Gzip 已禁用,占用内存方法 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2013-03-25   “共执行 41 个查询,用时 2 ...

随机推荐

  1. Spring:Spring-IOC简介

    想要了解控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想:依赖倒置原则(Dependency Inversion Principle ). 什么是依 ...

  2. 2013年第四届蓝桥杯C/C++程序设计本科B组省赛 马虎的算式

    题目描述 马虎的算式 小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了. 有一次,老师出的题目是:36 x 495 = ? 他却给抄成了:396 x 45 = ? 但结果却很戏剧性,他的答 ...

  3. python 常见面试问题

    https://blog.csdn.net/weixin_43789195/article/details/87469096 https://blog.csdn.net/qq_42642945/art ...

  4. 深入理解Java并发类——AQS

    目录 什么是AQS 为什么需要AQS AQS的核心思想 AQS的内部数据和方法 如何利用AQS实现同步结构 ReentrantLock对AQS的利用 尝试获取锁 获取锁失败,排队竞争 参考 什么是AQ ...

  5. C语言:预处理命令总结

    预处理指令是以#号开头的代码行,# 号必须是该行除了任何空白字符外的第一个字符.# 后是指令关键字,在关键字和 # 号之间允许存在任意个数的空白字符,整行语句构成了一条预处理指令,该指令将在编译器进行 ...

  6. C语言中函数的返回值

    规则 除局部变量的内存地址不能作为函数的返回值外,其他类型的局部变量都能作为函数的返回值. 我总结出下面这些规则: int.char等数据类型的局部变量可以作为函数返回值. 在函数中声明的指针可以作为 ...

  7. POJ 尺取法

    poj3061 Subsequence 题目链接: http://poj.org/problem?id=3061 挑战P146.题意:给定长度为n的数列整数a0,a1,...,a(n-1)以及整数S, ...

  8. 如何用css画一个彩虹---v客学院技术分享

    无意间看到了CSS radial-gradient() 函数实现了如下图的样式 仔细一看还真有点像灯光下的鸡蛋,O(∩_∩)O哈哈~ 今天我就来用radial-gradient()函数教大家画一个简单 ...

  9. python -- 程序异常与调试(异常处理)

    一.异常处理 针对在运行时可能会出错的语句块,可以提前设计好出现问题后的解决方案, 或者给出相应的提示信息.使用try-except语句来处理Python抛出的异常: # -------------- ...

  10. DNS Bind日志详述

    简介 在默认情况下,BIND9 把日志消息写到 /var/log/messages 文件中,而这些日志消息是非常少的,主要就是启动,关闭的日志记录和一些严重错误的消息:而将调试日志信息写入 BIND ...