Intellij Idea重构

开发的流程大致就是这样子的,测试先行算是推荐的。

  1. 编写测试->功能代码->修改测试->重构

上次在和buddy聊天的时候,才知道测试在功能简单的时候是后行的,在功能复杂不知道怎么下手的时候是先行的。

开始之前请原谅我对于Java语言的一些无知,然后,看一下我写的Main函数:

  1. package com.phodal.learing;
  2. public class Main {
  3. public static void main(String[] args) {
  4. int c=new Cal().add(1,2);
  5. int d=new Cal2().sub(2,1);
  6. System.out.println("Hello,s");
  7. System.out.println(c);
  8. System.out.println(d);
  9. }
  10. }

代码写得还好(自我感觉),先不管Cal和Cal2两个类。大部分都能看懂,除了c,d不知道他们表达的是什么意思,于是。

Rename

快捷键:Shift+F6

作用:重命名

  • 把光标丢到int c中的c,按下shift+f6,输入result_add
  • 把光标移到int d中的d,按下shift+f6,输入result_sub

于是就有

  1. package com.phodal.learing;
  2. public class Main {
  3. public static void main(String[] args) {
  4. int result_add=new Cal().add(1,2);
  5. int result_sub=new Cal2().sub(2,1);
  6. System.out.println("Hello,s");
  7. System.out.println(result_add);
  8. System.out.println(result_sub);
  9. }
  10. }

Extract Method

快捷键:alt+command+m

作用:扩展方法

  • 选中System.out.println(result_add);
  • 按下alt+command+m
  • 在弹出的窗口中输入mprint

于是有了

  1. public static void main(String[] args) {
  2. int result_add=new Cal().add(1,2);
  3. int result_sub=new Cal2().sub(2,1);
  4. System.out.println("Hello,s");
  5. mprint(result_add);
  6. mprint(result_sub);
  7. }
  8. private static void mprint(int result_sub) {
  9. System.out.println(result_sub);
  10. }

似乎我们不应该这样对待System.out.println,那么让我们内联回去

Inline Method

快捷键:alt+command+n

作用:内联方法

  • 选中main中的mprint
  • alt+command+n
  • 选中Inline all invocations and remove the method(2 occurrences) 点确定

然后我们等于什么也没有做了~~:

  1. public static void main(String[] args) {
  2. int result_add=new Cal().add(1,2);
  3. int result_sub=new Cal2().sub(2,1);
  4. System.out.println("Hello,s");
  5. System.out.println(result_add);
  6. System.out.println(result_sub);
  7. }

似乎这个例子不是很好,但是够用来说明了。

Pull Members Up

开始之前让我们先看看Cal2类:

  1. public class Cal2 extends Cal {
  2. public int sub(int a,int b){
  3. return a-b;
  4. }
  5. }

以及Cal2的父类Cal

  1. public class Cal {
  2. public int add(int a,int b){
  3. return a+b;
  4. }
  5. }

最后的结果,就是将Cal2类中的sub方法,提到父类:

  1. public class Cal {
  2. public int add(int a,int b){
  3. return a+b;
  4. }
  5. public int sub(int a,int b){
  6. return a-b;
  7. }
  8. }

而我们所要做的就是鼠标右键

重构之以查询取代临时变量

快捷键

Mac: 木有

Windows/Linux: 木有

或者: Shift+alt+command+T 再选择 Replace Temp with Query

鼠标: Refactor | Replace Temp with Query

重构之前

过多的临时变量会让我们写出更长的函数,函数不应该太多,以便使功能单一。这也是重构的另外的目的所在,只有函数专注于其功能,才会更容易读懂。

以书中的代码为例

  1. import java.lang.System;
  2. public class replaceTemp {
  3. public void count() {
  4. double basePrice = _quantity * _itemPrice;
  5. if (basePrice > 1000) {
  6. return basePrice * 0.95;
  7. } else {
  8. return basePrice * 0.98;
  9. }
  10. }
  11. }

重构

选中basePrice很愉快地拿鼠标点上面的重构

Replace Temp With Query Replace Temp With Query

便会返回

  1. import java.lang.System;
  2. public class replaceTemp {
  3. public void count() {
  4. if (basePrice() > 1000) {
  5. return basePrice() * 0.95;
  6. } else {
  7. return basePrice() * 0.98;
  8. }
  9. }
  10. private double basePrice() {
  11. return _quantity * _itemPrice;
  12. }
  13. }

而实际上我们也可以

  • 选中

_quantity * _itemPrice

  • 对其进行Extrace Method

  • 选择basePriceInline Method

Intellij IDEA重构

在Intellij IDEA的文档中对此是这样的例子

  1. public class replaceTemp {
  2. public void method() {
  3. String str = "str";
  4. String aString = returnString().concat(str);
  5. System.out.println(aString);
  6. }
  7. }

接着我们选中aString,再打开重构菜单,或者

Command+Alt+Shift+T 再选中Replace Temp with Query

便会有下面的结果:

  1. import java.lang.String;
  2. public class replaceTemp {
  3. public void method() {
  4. String str = "str";
  5. System.out.println(aString(str));
  6. }
  7. private String aString(String str) {
  8. return returnString().concat(str);
  9. }
  10. }