讲课案例11(单元测试与代码重构)

合集下载

单元测试代码例子 -回复

单元测试代码例子 -回复

单元测试代码例子-回复什么是单元测试?单元测试是软件开发中的一种测试方法,它用于验证程序的最小可测试单元是否按照预期进行工作。

这些最小可测试单元通常是函数、方法或类中的一部分代码。

单元测试的目的是在开发过程中尽早地检测和修复代码中的错误,以确保软件的质量。

为什么要进行单元测试?进行单元测试有以下几个主要原因:1. 完善代码质量:单元测试可以帮助开发者发现代码错误和潜在问题,确保代码按照预期工作。

通过及早发现和修复问题,可以提高整体代码质量。

2. 促进重构:单元测试可以确保代码重构后的正确性。

当进行代码重构时,没有单元测试的代码可能会导致不可预测的行为,而有单元测试的代码可以通过测试来验证重构后的正确性。

3. 增强代码可读性:编写单元测试需要将测试用例与被测试代码分离开来,这迫使开发者编写更加模块化和可测试的代码。

这种代码更易于阅读和维护。

4. 提高开发效率:单元测试可以自动化执行,减少手工测试的工作量。

在开发过程中,可以随时运行单元测试,并及时收到错误反馈,从而减少了调试和修复问题的时间。

如何进行单元测试?进行单元测试需要遵循以下步骤:1. 选择单元测试框架:根据编程语言和项目需求选择合适的单元测试框架。

常见的单元测试框架有JUnit、PyTest、Mocha等。

2. 编写测试用例:为每个被测试的函数或方法编写测试用例。

测试用例应该尽可能覆盖各种预期输入和边界情况,以验证代码的正确性。

3. 运行测试:使用单元测试框架运行编写好的测试用例。

运行测试时,框架会自动执行每个测试用例并记录结果。

4. 分析测试结果:检查测试结果,记录测试通过和失败的情况。

对于失败的测试用例,可以通过错误信息和调用栈来定位问题。

5. 调试和修复问题:对于失败的测试用例,通过调试来定位问题的原因,并修复代码以解决问题。

在修复问题后,重新运行测试以确认问题已经被修复。

6. 维护测试用例:随着代码的更新和修改,及时更新和维护测试用例,确保测试用例的覆盖率和有效性。

单元测试与重构

单元测试与重构

谢谢
软件业务部
平台开发部

11
改善设计、软件更易理解、更易Debug、提高开发效率……
单元测试与重构的关系
单元测试是重构的信心!
重构是高效单元测试的保证!
今天讲些什么
Junit、spring-test、Dbunit、EasyMock
重构
今天讲些什么
我们定义这样一个案例:
这是某个系统中的菜单模块,我们需要对每个 菜单点击事件进行响应,在响应之前我们需要 验证点击的用户是否拥有合法的权限。
附录B——代码的坏味道1
重复的代码 过长的函数 过大的类 过长参数列 发散式变化 霰弹式修改 依恋情结 数据泥潭 基本类型偏执 Switch惊悚现身 平行继承体系 冗赘类
附录B——代码的坏味道2
夸夸其谈未来性 令人迷惑的暂时值域 过度耦合的消息链 中间转手人 狎昵关系 异曲同工的类 不完善程序库类 纯稚的数据类 被拒绝的遗赠 1
2 3 4
为什么要单元测试 为什么要重构 单元测试与重构的关系 今天讲些什么
为什么要单元测试
作为一个程序员,Debug占用的时间是最多 的!
而Bug修复易,定位难! 忙活了一天,只是修复了一个很“简单”的 bug,你中招没。。。
为什么要重构
问渠那得清如许,为有源头活水来!
好处:
附录A——面向对象设计原则
单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。 开放、封闭原则:软件实体应该是可以扩展的,但是不可修改的。 Liskov替换原则:子类型必须能够替换掉他们的基类型。 依赖倒置原则:高层模块不应该依赖底层模块,二者应该依赖于抽象, 抽象不应该依赖于细节,细节应该依赖于抽象。 接口隔离原则:类的接口应该是内聚的,否则就应该进行隔离。

软件测试中的代码重构和优化技巧

软件测试中的代码重构和优化技巧

软件测试中的代码重构和优化技巧随着软件开发的不断发展,代码重构和优化成为了软件测试中不可或缺的一部分。

代码重构是指通过改变代码的结构和设计,使其更易于理解和维护,而代码优化则是通过改进代码的性能和效率,使其更加高效。

本文将探讨软件测试中的代码重构和优化技巧,帮助开发人员提高代码质量和测试效果。

一、代码重构技巧1. 提取公共方法和类:在软件开发过程中,经常会出现一些重复的代码片段。

为了提高代码的可读性和可维护性,我们可以将这些重复的代码提取成公共方法或类。

这样不仅可以减少代码量,还可以避免重复的修改工作。

2. 消除代码重复:代码重复是软件开发中常见的问题,它不仅降低了代码的可读性,还增加了维护的难度。

通过使用循环、函数和类等技术,我们可以消除代码重复,提高代码的可维护性。

3. 优化条件判断:在软件测试中,经常会出现大量的条件判断语句。

为了提高代码的可读性和性能,我们可以使用多态、策略模式等技术来优化条件判断。

这样不仅可以减少代码量,还可以提高代码的可扩展性。

4. 重构复杂的方法:在软件开发过程中,经常会出现一些复杂的方法,它们包含了大量的代码和逻辑。

为了提高代码的可读性和可维护性,我们可以将这些复杂的方法进行拆分和重构。

通过使用单一职责原则和开闭原则等技术,我们可以将复杂的方法拆分成多个简单的方法,使其更易于理解和维护。

二、代码优化技巧1. 减少循环次数:在软件测试中,循环是一种常见的结构,它用于处理大量的数据。

为了提高代码的性能,我们可以减少循环次数。

可以通过使用缓存、使用更高效的数据结构等技术来减少循环次数,提高代码的执行效率。

2. 使用合适的数据结构:在软件测试中,选择合适的数据结构对于代码的性能至关重要。

不同的数据结构适用于不同的场景,选择合适的数据结构可以提高代码的执行效率。

比如,使用哈希表可以快速查找数据,使用链表可以高效地插入和删除数据。

3. 优化数据库操作:在软件测试中,数据库操作是一个常见的性能瓶颈。

c语言单元测试实例

c语言单元测试实例

C语言单元测试实例1. 什么是单元测试?单元测试是软件开发中的一种测试方法,用于验证程序的最小可测试单元(通常是函数)是否按照预期进行工作。

单元测试可以帮助开发人员快速发现和修复代码中的错误,提高软件质量和可靠性。

在C语言中,单元测试通常使用测试框架来编写和运行测试用例。

常见的C语言单元测试框架包括Unity、Check、CppUTest等。

这些框架提供了丰富的断言和测试工具,使得编写和执行单元测试变得更加方便和高效。

2. 单元测试的优势单元测试具有以下几个优势:2.1 提高代码质量通过编写单元测试,可以对代码进行全面的覆盖,发现潜在的bug和错误。

单元测试可以帮助开发人员及时修复问题,保证代码的质量。

2.2 改善代码设计为了编写可测试的代码,开发人员需要将代码分解为更小的模块,提高代码的可维护性和可测试性。

单元测试可以促使开发人员遵循良好的设计原则,如单一职责原则、依赖倒置原则等。

2.3 提高开发效率单元测试可以快速发现问题,减少调试时间。

通过自动化运行单元测试,可以快速验证代码的正确性,提高开发效率。

2.4 支持重构重构是改进代码质量的重要手段,但重构可能引入新的bug。

通过编写单元测试,可以确保重构后的代码仍然正确工作,提高重构的安全性。

3. C语言单元测试框架3.1 UnityUnity是一个轻量级的C语言单元测试框架,适用于嵌入式系统和低资源环境。

Unity提供了丰富的断言和测试工具,支持测试组织和运行。

以下是一个使用Unity编写的简单的单元测试示例:#include "unity.h"#include "my_math.h"void test_add(void) {TEST_ASSERT_EQUAL_INT(3, add(1, 2));}int main(void) {UNITY_BEGIN();RUN_TEST(test_add);return UNITY_END();}在上面的示例中,我们使用了TEST_ASSERT_EQUAL_INT宏来断言函数add的返回值是否等于3。

代码重构的技巧与方法

代码重构的技巧与方法

代码重构的技巧与方法代码重构是软件开发过程中的关键步骤,它可以提高代码质量、可读性和可维护性。

本文将介绍一些代码重构的技巧与方法,帮助开发者改进现有代码,使其更加高效和可靠。

一、重构的概念与原则代码重构是通过对现有代码的修改,改进其结构、设计和性能,而不改变其可观察行为的过程。

在进行代码重构时,需要遵循以下原则:1. 保持代码的功能不变:代码重构的目标是改进代码质量,而不是改变代码的功能。

2. 小步重构:将大的重构任务分解为多个小步骤,每次只修改少量的代码,通过多次迭代达到重构的目标。

3. 频繁重构:在开发过程中,持续进行代码重构,而不是等到代码出现问题再进行改进。

二、常用的代码重构方法1. 提取方法(Extract Method):将一个长方法中的部分代码提取出来,封装为一个独立的方法,提高代码的可读性和复用性。

2. 内联方法(Inline Method):当一个方法中的代码变得简单明了时,可以将其内联到调用处,减少不必要的方法调用。

3. 提取变量(Extract Variable):将复杂的表达式或者重复使用的字面量提取为一个变量,使代码更易理解和维护。

4. 函数改名(Rename Method):当一个方法的命名不清晰或者不符合代码风格时,应给其一个更合适的命名,提高代码可读性。

5. 移动方法(Move Method):当一个方法与另一个类更相关时,可以将其移动到相应的类中,增加代码的内聚性和可维护性。

6. 合并方法(Inline Method):当一个方法的逻辑与其他方法高度相似时,可以将其合并为一个方法,减少代码冗余。

7. 提取接口(Extract Interface):当一个类需要与其他类进行交互时,可以抽象出一个接口,提高代码的扩展性和灵活性。

8. 拆分循环(Split Loop):当一个循环中包含多个不同的逻辑时,可以将其拆分为多个循环,提高代码的可读性和性能。

9. 合并循环(Merge Loop):当多个循环中的逻辑相似且没有依赖关系时,可以将其合并为一个循环,简化代码结构。

代码重构实践案例分析

代码重构实践案例分析

代码重构实践案例分析代码重构是软件开发过程中一项非常重要的技术活动,它旨在通过优化已有代码的结构和性能,提高代码的可读性、维护性和可扩展性。

在本文中,将通过分析一个实际的代码重构案例,来探讨代码重构的方法和技巧,以及它对软件开发的影响。

一、背景介绍在某个软件开发项目中,开发团队遇到了一个大型的、复杂的代码库,其中包含着大量已经交付的代码。

随着项目的发展,这些代码变得越来越难以理解和维护。

开发团队决定对这些代码进行重构,以提高其质量和可维护性。

二、分析与规划在开始进行代码重构之前,开发团队对现有代码进行了全面的分析和评估。

他们发现代码存在以下问题:1. 重复代码:代码中存在大量的重复代码,不仅增加了维护的难度,还增加了错误发生的概率。

2. 长方法:某些方法过长,包含了太多的逻辑,不利于理解和维护。

3. 紧耦合:代码之间存在过多的依赖关系,修改一个功能可能会引起整个系统的崩溃。

4. 低内聚:某些类的职责不够清晰,存在着不必要的依赖关系。

基于对这些问题的分析,开发团队制定了代码重构的规划:1. 消除重复代码:通过抽取公共方法、引入设计模式等方式,消除代码中的重复部分。

2. 方法分解:将过长的方法分解成多个独立的小方法,提高代码的可读性和可维护性。

3. 解耦合:通过引入接口、抽象类等方式,解除代码的紧耦合关系。

4. 提高内聚性:对职责不清晰的类进行重构,将其划分为更加独立和可重用的部分。

三、重构实施在进行代码重构之前,开发团队制定了详细的计划和时间表,并与项目经理和其他相关人员进行了沟通。

在实施代码重构时,他们采用了以下步骤:1. 单元测试:对即将进行重构的代码编写详尽的单元测试,以保证重构后的代码的正确性和稳定性。

2. 逐步重构:将代码重构任务划分为多个小步骤,逐步进行,每次重构后运行单元测试,确保功能的正确性和稳定性。

3. 代码评审:在重构过程中,开发团队定期进行代码评审,以确保重构目标的正确理解和实施。

单元测试代码例子 -回复

单元测试代码例子 -回复

单元测试代码例子-回复单元测试是软件开发中至关重要的一环,它帮助开发人员检验、验证和维护自己的代码。

在本文中,我们将以"单元测试代码例子"为主题,详细解释单元测试的概念、重要性以及如何使用Python编写单元测试代码的例子。

# 第一步:了解单元测试的概念在软件开发过程中,代码的测试是十分重要的,它有助于发现和解决潜在的问题和错误。

单元测试是测试过程中的一种方法,它专注于验证代码的最小可测试单元,通常是一个函数或方法。

通过单元测试,开发人员可以确保每个代码单元的功能正确性和稳定性。

单元测试的目标是隔离和测试代码的独立单元,而不是测试整个系统的功能。

这样可以帮助开发人员保证每个单元在不同的情况下都能正确地工作,而不需要依赖于其他部分的代码。

# 第二步:说明单元测试的重要性单元测试的重要性在于它通过自动化测试代码的方式,提供了一种快速、可靠和可重复的测试方法。

以下是单元测试的几个重要优势:1. 发现潜在问题:通过执行针对代码单元的测试,可以发现并解决潜在的问题和错误。

这有助于提高代码的质量,并减少在开发过程中的错误。

2. 维护代码质量:随着软件的迭代和持续开发,代码会不断演化和修改。

通过编写单元测试代码,开发人员可以确保已有的代码在每次修改后仍然正确工作,从而保持整个系统的稳定性。

3. 提高开发效率:单元测试自动化了测试过程,减少了手动验证代码的工作量。

开发人员只需要编写一次测试代码,在需要时可以随时运行。

这样可以节省时间,同时提高开发效率。

4. 便于代码维护:单元测试与被测试代码解耦,这使得在修改代码时能够更加自信地知道是否影响了其功能。

当发现错误时,可以迅速定位问题并修复,不会对其他代码单元造成负面影响。

# 第三步:使用Python编写单元测试代码的例子以下是一个简单的Python函数的例子,我们将编写对其进行单元测试的代码。

pythondef add(a, b):return a + b编写单元测试代码的第一步是导入Python的unittest模块。

单元测试及其案例分析

单元测试及其案例分析

单元测试及其案例分析什么是单元测试单元测试是软件开发中的一种测试方法,用于检查程序中的最小可测试单元(通常是函数或方法)是否按预期正常工作。

单元测试通常由开发人员编写,并可以在代码修改后快速运行,确保代码的质量和稳定性。

单元测试的优点1.提高代码质量:通过单元测试可以发现代码中的错误和潜在问题,确保代码质量更高。

2.快速反馈:单元测试可以快速执行,及时发现问题并进行修复。

3.简化代码重构:单元测试可以保证代码重构后不会破坏原有功能,让开发人员更有信心地进行重构。

4.提高可维护性:有了单元测试,当需求修改时可以快速验证代码是否仍然有效,减少修改代码后引入的新问题。

5.促进团队合作:单元测试可以让团队成员更容易理解代码的功能和预期行为。

单元测试的案例分析假设我们有一个简单的计算器程序,包含加法、减法、乘法和除法四种功能。

我们可以通过编写单元测试来确保每个功能的正确性。

加法函数的单元测试def add(a, b):return a + bdef test_add():assert add(1, 2) ==3assert add(-1, 1) ==0减法函数的单元测试def subtract(a, b):return a - bdef test_subtract():assert subtract(3, 2) ==1assert subtract(5, 5) ==0乘法函数的单元测试def multiply(a, b):return a * bdef test_multiply():assert multiply(2, 3) ==6assert multiply(-1, 5) ==-5除法函数的单元测试def divide(a, b):if b ==0:return Nonereturn a / bdef test_divide():assert divide(6, 3) ==2assert divide(8, 0) is None通过以上单元测试案例,我们可以确保计算器程序中的加法、减法、乘法和除法功能在输入正确时都能按预期正常工作,帮助开发人员提高代码质量和稳定性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

讲课案例11(单元测试与代码重构)一、单元测试【单元测试基础案例】现有一个MyMath类,实现了一个“从两个整数中选择最大者”的getMax()方法和一个“从三个整数中选择最大者”的getMax()方法(见案例代码)。

编写一个TestMyMath测试类,对这两个方法分别进行单元测试,尽可能发现其中的Bug(暂不修复)。

(1)编写测试时,首先考虑验证每个方法的功能是否正确。

(2)然后考虑边界条件。

(3)思考:没有全面的单元测试,你能发现产品代码中的大量缺陷吗?(4)掌握JUnit框架的基本用法及Assert类的基本用法。

【单元测试基础案例】现有一个Product产品类,实现了一个“从一组整数中求最大数”的方法(见案例代码)。

编写一个TestProduct 测试类,对该方法进行单元测试,尽可能发现其中的Bug。

(1)编写测试时,首先考虑正常的情况。

(2)考虑边界条件。

(3)考虑异常情况,并进行异常情况的测试。

(4)对发现的Bug进行修复,并进行回归测试。

(5)掌握JUnit中异常测试的基本方法。

【计算逻辑测试案例】模拟一个购物车,顾客可以向购物车中添加多个商品并可以查看购物清单和应付款项。

每个条目应当包括商品名、单价、数量等基本信息。

若每件商品都有相应的打折规则,如何计算出应付款项?(1)假设打折规则如下:◆单项打折:若商品单价超过100元,则对该商品打7折;若商品单价超过50元但小于等于100元,则对该商品打8折;若商品单价小于等于50元,则对该商品打9折。

◆总额打折:一次购物的总额(单项打折后)若超过300元,则再对总额打9折,否则不再对总额打折。

(2)设计关键点:使用一个结算对象来专门进行应付款项的计算。

(3)使用JUnit对结算对象进行单元测试,并修复所有的Bug。

(4)总结:编写单元测试时,先进行基本功能验证,再考虑复杂测试用例、边界条件、白盒测试用例等情况。

【算法测试案例】编写一个冒泡排序算法,对一组整数进行排序,用户既可以升序排序,也可以降序排序。

分别对这两个方法进行单元测试。

public class BubbleSort{public int[] ascSort(int[] a){for(int i=1;i<a.length;i++)for(int j=0;i<a.length-i;j++)if(a[j]>a[j+1]){int temp=a[j];a[j]=a[j+1];a[j+1]=temp;}return a;}public int[] descSort(int[] a){for(int i=1;i<a.length;i++)for(int j=0;j<a.length-i;i++)if(a[j]<a[j+1]){int temp=a[j];a[j]=a[j+1];a[j+1]=temp;}return a;}}(1)使用Assert.assertArrayEquals()方法可以对两个数组是否等价进行验证。

(2)先考虑基本功能验证,再考虑特殊情况。

修复发现的所有Bug。

【异常测试案例】现有一个可以保存任意对象的MyStack<T>堆栈类,该堆栈的大小可以在创建时指定。

并且该堆栈在栈空时弹栈会抛出“栈空不能弹栈”的异常,在栈满时入栈会抛出“栈满不能入栈”的异常。

(1)首先编写一组测试用例,对MyStack<T>的push()和pop()操作的正确性进行验证。

(2)然后对“栈空不能弹栈”的异常进行测试。

(3)再对“栈满不能入栈”的异常进行测试。

(4)再对堆栈初始化的异常进行测试。

【性能测试案例】在Fibonacci数列案例中,自行设计和定义一个MyBigInteger类,实现add( )方法,替换掉Java类库中的BigInteger 类。

(1)自己编写一个MyBigInteger类,实现大整数的存储和求和。

(2)注意计算中的性能问题。

(3)在单元测试中构造两个超大整数(每个超大整数有两万位),进行求和,设定超时时间为100毫秒(即@Test(timeout=100)),观察测试是否会失败?(4)思考:能否改进求和算法?【复杂逻辑测试案例】现有一个Calendar类,可以计算出给定日期的前一天日期和后一天日期(例如,若给定一个日期为2005.3.24,则该类可以计算出该日期的前一天日期为2005.3.23,后一天日期为2005.3.25)。

(1)首先简单地测试该类的计算功能是否正确。

(2)思考:有几种方法可以判定两个日期对象相同?(3)然后使用如下的一组测试用例,进行功能测试。

(4)再使用无效日期(如2003年3月35日)进行异常测试,并预期其行为。

修复所有测试出的Bug。

(5)一些日期示例:【字符串测试案例】判断一个给定的字符串是否是“回文串”(Palindrome)。

回文是指正读和反读都相同的字符序列,例如,“abcba”是回文串,但“abcde”不是回文串。

首先编写出该Palindrome类,然后对其进行单元测试,并考虑空引用、空白串、单字符串等特殊情况,最后修复所有Bug和进行回归测试。

【泛型容器测试案例】编写一个MyArrayList<T>泛型类,可以按顺序表的方式操作一组相同类型的对象。

编写该类的同时,从其功能角度考虑,编写出全面的单元测试。

(1)严格测试公共泛型接口IList中规定的全部方法。

(2)注意对MyArrayList类应当测试异常。

(3)课后作业:为自己以前编写的泛型容器类(如哈希表、二叉排序树、映射表、集合等)逐个编写单元测试,验证其质量如何。

改进:单元测试中的模拟对象讲解应当先给一个相互依赖对象的实例,通过测试发现错误,但是很难定位错误,从而说明解耦两个相互依赖对象的重要性。

【测试桩案例】被测类EmployeeService中有一个方法getTotalSalary( ),用来计算出一组员工的总薪水(见案例代码)。

这组员工对象由一个数据访问对象从数据库中读取,但目前没有数据库支持,无法读取员工信息。

现在如何测试该方法?(1)首先提取数据访问对象的接口IDao。

(2)编写一个自定义的Dao类实现该接口。

(3)在测试EmployeeService的getTotalSalary()方法时使用依赖注入将Dao对象传入,并预期测试结果。

(4)总结:测试桩使用一个模拟对象替代实际对象以顺利完成对被测对象的单元测试。

【模拟对象案例1】被测类Calculator中有一个方法compute(),用来计算f(n)=n+n!+n!+2n的值,其中,计算n!及2n的方法都由一个依赖类提供,但是目前该依赖类还未编写完成。

试定义出该依赖类的接口,然后使用jmock模拟对象来独立地完成被测类Calculator的单元测试。

(1)首先定义出该依赖类的接口IMath。

(2)使用JMock库创建一个实现了IMath接口模拟对象,并规定好预期返回值。

(3)在单元测试中给被测对象Calculator传入模拟对象,并检查其计算结果是否正确。

(4)总结:模拟对象解除了被测对象与依赖对象之间的耦合,使得对被测对象进行单元测试变得方便。

【模拟对象案例2】Tom总是随身带着一个钱包,我们想向Tom借300元钱。

在包中已经编写好了Person类和Wallet类。

(1)Wallet类封装从钱包中取钱的逻辑。

(2)Person类封装一个钱包对象和借钱的逻辑。

(3)包中封装Wallet类和Person类,并且隐藏Wallet类,只公开Person类。

(4)测试要求:先对Wallet类做单元测试,再用JMock对象模拟Wallet类(提取IWallet接口),对Person类的借钱方法做单元测试。

二、代码重构【重构基础案例】现有一个MyMath类,实现了一个“从两个整数中选择最大者”的getMax()方法和一个“从三个整数中选择最大者”的getMax()方法(见案例代码)。

已经编写了单元测试,并发现了几个Bug。

(1)首先修复所有的Bug,使测试全部通过。

(2)改进两个getMax()方法内部实现代码,提升代码的重用度和可读性。

同时保证单元测试仍然能够全部通过。

(3)总结:通过代码重构加深了我们对代码逻辑的理解和认识。

【显示效果重构案例】现有一个ChessBoard棋盘类,包含一个show ()方法,显示该棋盘的形状。

该方法中的代码很长,试进行重构,要求棋盘的显示效果不变。

(1)代码坏味道之一:过长的方法。

(2)代码坏味道之二:重复的代码。

(3)重构手法之一:提炼方法。

(4)重构手法之二:组合方法。

(5)要点:重构时要注意节奏,小步前进。

【算法重构案例】现有一个冒泡排序算法类(BubbleSort),能对一组整数进行排序,用户既可以升序排序,也可以降序排序,并且已经通过了单元测试。

public class BubbleSort{public static int[] ascSort(int[] a){if(a==null)throw new IllegalArgumentException("数组不能为null");for(int i=1;i<a.length;i++)for(int j=0;j<a.length-i;j++)if(a[j]>a[j+1]){int temp=a[j];a[j]=a[j+1];a[j+1]=temp;}return a;}public static int[] descSort(int[] a){if(a==null)throw new IllegalArgumentException("数组不能为null");for(int i=1;i<a.length;i++)for(int j=0;j<a.length-i;i++)if(a[i]<a[j+1]){int temp=a[j];a[j]=a[j+1];a[j+1]=temp;}return a;}}(1)代码坏味道:重复的代码。

(2)重构手法:提炼接口。

定义一个IComparator接口,包含一个comapre(int , int)方法,比较两个整数的大小。

(3)重构手法:提炼方法和增加参数。

将排序代码提取至一个私有方法中,并增加一个比较器对象作为参数,替换比较表达式。

(4)定义两个匿名的比较器对象传给方法,完成升序和降序排序。

(5)重新运行单元测试,保证测试全部通过。

【性能改进案例】在Fibonacci数列案例中,自行设计和定义一个MyBigInteger类,实现add( )方法,替换掉Java类库中的BigInteger 类。

相关文档
最新文档