> For the complete documentation index, see [llms.txt](https://ethan-lin.gitbook.io/refactoring/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ethan-lin.gitbook.io/refactoring/dan-wei-zhuan-huan/6-change-function-declarations.md).

# 任务4：改变函数参数

将字符串提炼成为常量，事实上已经消除了“重复代码”的坏味道：现在要修改字符串的值，只需要修改一处地方了。不过，提炼出常量以后，我们又发现一个事情，那就是这个常量本身的值是什么，其实也不重要了——它应该是一个典型的`Enum`类型。如果是使用 JavaScript 的同学，可能会发现 JS 中没有枚举`Enum`类型，那么至少我们可以把这个常量搬移到类外面。

这节课要做的事，就是：

* 使用 Java 的同学：把所有字符串常量的引用点，替换对枚举值的处理/引用。
* 使用 JavaScript 的同学：确保字符串常量搬移到了`Length`类的外面。

不过，这一步的任务粒度稍大，请你在开始之前先花 3 分钟思考一下：你将如何重构？你能否做到每写几行代码都能运行测试（而不是全部做完再运行一次测试）？

![](/files/-Lr9XDTb44nl7goQjSEr)

## 你的任务

### JavaScript

```
git checkout task-4
npm test
```

对于使用 JavaScript 的同学来说，由于 JS 是弱类型，这个任务可能简单一些：你只需要把常量文件从`Length`文件内搬移到另一个文件里（如果上一步还没这么做），确保测试全部通过，就可以了。

1. 将字符串常量搬移到`Length`类外
2. 注意重构的步子，保持每分钟都要能运行测试

### Java

```
git checkout task-4
./gradlew test
```

对于 Java 的同学来说，这步任务的粒度就要稍微大一点了，因为 Java 是强类型的语言，要把`String`类型的单位字符串替换成不同类型的`enum`，需要改动所有地方的函数签名：构造函数、`getUnit()`方法，以及`setter`方法。

从哪里开始重构呢？如何做到平滑替换呢？如何做到每分钟都能保持测试通过呢？这就是你需要考虑和练习的问题。

1. 将以下所有使用字符串常量的地方替换成枚举类型：
   * `getUnit()` setter 方法
   * 构造函数
   * `parseTo()`/`as()`方法
2. `git checkout task-6`看一下参考步骤，找出与你设定步骤的异同
3. 多练几遍

## 思考

* 你选择先更换哪个方法的声明？你觉得重构的先后次序有区别吗？
* 过程中有没有不顺畅的地方？
* 你还能做到重构过程每分钟都保持运行测试并且测试通过的状态吗？

## 参考资料

* 《重构 2》6.5 改变函数声明（Change Function Declaration）
* 《重构 2》6.7 变量改名（Rename Variable）


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ethan-lin.gitbook.io/refactoring/dan-wei-zhuan-huan/6-change-function-declarations.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
