《重构改善既有代码的设计》之重构列表--重新组织函数(三)

2023-12-16 14:58

本文主要是介绍《重构改善既有代码的设计》之重构列表--重新组织函数(三),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

七、Remove Assignments to Parameters(移除对函数的赋值)

代码对一个参数进行赋值

以一个临时变量取代该参数的位置

Int discount(int inputVal,int quantity,int yearToDate){

If(inputVal > 50)

    inputVal -= 2;

}

转换后:

Int discount(int inputVal,int quantity,int yearToDate){

Int result = inputVal;

If(inputVal > 50)

    result -= 2;

}

动机

首先,我要确定大家都清楚“对参数赋值”这个说法的意思。如果你把一个名为foo的对象作为参数传给某个函数,那么“对参数赋值”意味着改变foo,使它引用另一个对象。如果你在“被传入参数”身上进行什么操作,那没问题,我也总是这样干。我只针对“foo被改变而指向另个一个对象”这种情况讨论:

Void aMethod(Object foo){

foo.modifyInSomeWay();//that is ok.

Foo = anotherObject;//trouble and despair will follow you.

}

在按值传递的情况下,对参数的任何修改,都不会对调用端造成任何影响。那些用过按引用传递方式的人可能会在这一点上犯糊涂。

另一个让人糊涂的地方是函数本体内。如果你只以参数表示“被传递进来的东西”,那么代码会清晰很多,因为这种用法在所有语言中都表现出相同语义。

Java中,不要对参数赋值:如果你手上的代码已经这样做了,请使用Remove Assignments to Parameters.

做法

1、建立一个临时变量,把待处理的参数值赋予它。

2、以“对参数赋值”为界,将其后所有对此参数的引用点,全部替换为“对此临时变量的引用”。

3、修改赋值语句,使其改为对新建之临时变量赋值。

4、编译、测试。

八、Replace Method with Method Object(以函数对象取代函数)

你有一个大型函数,其中对局部变量的使用使你无法采用Extract Method

将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的字段。然后你可以在同一个对象中将这个大型函数分解为多个小型函数。

Class Order ....

  Double price(){

    Double  primaryBasePrice

Double  secondaryBsePrice;

Double  teriaryBasePrice;

//long computation

  }

动机

有时局部变量的存在会增加函数分解的难度。如果一个函数之中局部变量泛滥成灾,那么想分解这个函数是非常困难的。Replace Temp with Query可以助你减轻这一负担,但有时候你会发现根本无法拆解需要拆解的函数。这种情况下,你应该把手伸进工具箱的深处,祭出函数对象这一法宝。

Replace Method with Method Object会将所有局部变量都变成函数对象的字段。然后你就可以对这个新对象使用Extract Method创造出新函数,从而将原本的大型函数拆解变短。

做法

1、建立一个新类,根据待处理函数的用途,为这个类命名。

2、在新类中建立一个final 字段,用以保存原先大型函数所有的对象。我们将这个字段成为“源对象”。同时,针对原函数的每个临时变量和每个参数,在新类中建立一个对应的字段保存之。

3、在新类中建立一个构造函数,接受源对象以及原函数的所有参数作为参数。

4、在新类中建立一个compute()函数。

5、将原函数的代码复制到compute()函数中。如果需要调用源对象的任何函数,请通过源对象调用。

6、编译

7、将旧函数的函数本体替换为这样一条语句:“创建上述新类的一个新对象,而后调用其中的compute()函数”。

九、Sustitute Algorithm(替换算法)

你想要把某个算法替换为另一个更清晰的算法。

将函数本体替换为另一个算法。

String foundPerson(String[] people){

For(int i =0;i<people.length;i++){

If(people[i].equals("Don")){

Return "Don";

}

If(people[i].equals("Json")){

Return "Json";

}

If(people[i].equals("Kent")){

Return "Kent";

}

}

Return "";

}

转换后:

String foundPerson(String[] people){

List candidates = Arrays.asList(new String[] {"Don","Json","Kent"});

For(int i = 0 ;i<people.length;i++){

If(condidates.contains(people[i])){

Return people[i];

}

}

}

动机

如果你发现做一件事可以有更清晰的方式,就应该以较清晰的方式取代复杂的方式。

做法

1、准备好另一个(替换用)算法,让它通过编译。

2、针对现有测试,执行上述新算法。如果结果和原本结果相同,重构结束。

3、如果测试结果不同于原先,在测试和调试过程中,以就算法为比较参照标准。

注:对于每一个测试用例,分别以新旧两种算法执行,并观察两者结果是否相同。这可以帮助你看到哪一个测试用例出现麻烦,以及出现了怎样的麻烦。

这篇关于《重构改善既有代码的设计》之重构列表--重新组织函数(三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500876

相关文章

使用Redis实现会话管理的示例代码

《使用Redis实现会话管理的示例代码》文章介绍了如何使用Redis实现会话管理,包括会话的创建、读取、更新和删除操作,通过设置会话超时时间并重置,可以确保会话在用户持续活动期间不会过期,此外,展示了... 目录1. 会话管理的基本概念2. 使用Redis实现会话管理2.1 引入依赖2.2 会话管理基本操作

mybatis-plus分表实现案例(附示例代码)

《mybatis-plus分表实现案例(附示例代码)》MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生,:本文主要介绍my... 目录文档说明数据库水平分表思路1. 为什么要水平分表2. 核心设计要点3.基于数据库水平分表注意事项示例

Nginx服务器部署详细代码实例

《Nginx服务器部署详细代码实例》Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,:本文主要介绍Nginx服务器部署的相关资料,文中通过代码... 目录Nginx 服务器SSL/TLS 配置动态脚本反向代理总结Nginx 服务器Nginx是一个‌高性

Python容器转换与共有函数举例详解

《Python容器转换与共有函数举例详解》Python容器是Python编程语言中非常基础且重要的概念,它们提供了数据的存储和组织方式,下面:本文主要介绍Python容器转换与共有函数的相关资料,... 目录python容器转换与共有函数详解一、容器类型概览二、容器类型转换1. 基本容器转换2. 高级转换示

Python列表的创建与删除的操作指南

《Python列表的创建与删除的操作指南》列表(list)是Python中最常用、最灵活的内置数据结构之一,它支持动态扩容、混合类型、嵌套结构,几乎无处不在,但你真的会创建和删除列表吗,本文给大家介绍... 目录一、前言二、列表的创建方式1. 字面量语法(最常用)2. 使用list()构造器3. 列表推导式

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param