转载请声明,转载自【https://www.cnblogs.com/andy-songwei/p/11809700.html】,谢谢!

       代码重构几乎是每个程序员在软件开发中必须要不断去做的事情,以此来不断提高代码的质量。Android Stido(以下简称AS)以其强大的功能,成为当下Android开发工程师最受欢迎的开发工具,也是Android官方推荐使用的工具。如此优秀的工具,自然少不了要在代码重构这件事情上好好表现一把了。本文将通过代码演示,功能截图来详细介绍AS为代码重构提供的各项功能。

       在AS的主菜单栏中有一项“Refactor”下拉菜单,点击该下拉菜单,会看到如下的界面,菜单中的每一项,都是为代码重构提供的一项自动实现功能。这么多的功能项,可见AS在代码重构功能上的强大,下面我们对这些功能项一一进行介绍。另外,还可以在编辑界面中点击右键,在弹出的菜单中也可以找到“Refactor”。

 

1、Refactor This

       作用:重构当前。操作此项,会显示对当前光标选中处可行的重构方法。

       示例:选择了类名“RefactorTest”,操作“Refactor This”后,显示了可执行的重构方法列表,可以通过选择数字来执行对应的方法。

       

 

2、Rename

       作用:对光标选中项进行重命名。不仅可以对类中的成员变量进行重命名,还能对文件名,包名等进行重命名,Module中与之相关联的所有地方都会一起修改,而不用一一手动修改。

       快捷键:Shift + F6

       示例:在红框中输入修改后的名称,并按Enter键即可。

 

3、Rename File

       作用:修改当前编辑界面显示的文件的文件名。就相当于鼠标选中该文件,并执行“Rename”方法。

       示例:在显示的对话框中输入新文件名。可以在下方的选项框中选择修改范围,引用该文件的地方,注释,字符串中都可以选择一起修改。

 

4、Change Signature

       作用:修改方法、类、构造函数的签名,其实就是修改所选项的一些属性。

       快捷键:Ctr l+ F6

       示例:如下展示了一个方法重构前,重构过程,以及重构后的情形(以修改一个方法签名为例)。

       重构前:

1 private void testChangeSignature(int first, int second) {2 }

选中方法名后,执行该重构方法后,会弹出如下对话框,可以对该方法各种属性进行修改,添加/删除参数,调整参数顺序,新增/删除异常等。

        重构后:

1 public void testChangeSignature(int second, int first, String third) throws NullPointerException {2 }

 

5、Type Migration

       作用:类型迁移,即对变量数据类型,或者方法的返回类型进行修改。前面介绍了对文件名,包名,变量名等进行修改,这里对类型进行修改。

       快捷键:Ctrl + Shift + F6

       重构前:

1 private int age = 10;2 public RefactorTest(int age) {3     this.age = age;4 }

选中要修改的类型,执行该重构方法,会弹出对话框,根据需要编辑类型,选中作用范围即可。指定范围内,与该变量相关联处都会被修改。

重构后(由于从int修改到String,所以还需要手动修改变量值): 

1 private String age = "10";2 public RefactorTest(String age) {3     this.age = age;4 }

 

  6、Make Static

       作用:给内部类或者方法添加static关键字。示例比较简单,就不做演示了。

       

  7、Convert To Instance Method

       作用: 转换为实例方法,即将静态方法去掉static关键字。

 

  8、Move

       功能:移动文件到指定路径

       快捷键:F6

 

9、Copy

       作用:在指定包中拷贝一份当前文件

       快捷键:F5

 

10、Safe Detele

       作用:安全删除,可用于对方法/字段等进行快速删除,会删除掉与之相关联的引用。

       快捷键:Alt + Delete

 

 

11、Extract

   (1)Variable 

       作用:提取变量。这一点在碰到比较长的表达式时经常用到,将看起来很长很复杂的表达式提取出来作为一个变量表示。

       快捷键:Ctrl + Alt + V

       重构前:我们常会看到这样的代码

1 public void testExtractVariable() {2      Log.i("demo", "age=" + getAaaaaaaaaaaaaaaaaaaaaaaaaaaAge() + ";name=" + getNnnnnnnnnnnnnnnnnnnnnnname());3  }4  private int getAaaaaaaaaaaaaaaaaaaaaaaaaaaAge() {5      return age;6  }7  private String getNnnnnnnnnnnnnnnnnnnnnnname() {8      return name;9  }

第二行的要打印的信息表达式太长了,希望单独提取出来用一个变量表示。本示例中鼠标停留在第2行“getAaaaaaaaaaaaaaaaaaaaaaaaaaaAge”处,执行该重构方法,会弹出如下红框部分对话框,显示的是选中表达式相关的可提取部分,根据需要选择要提取的部分即可。

重构后: 

 1 public void testExtractVariable() { 2     String msg = "age=" + getAaaaaaaaaaaaaaaaaaaaaaaaaaaAge() + ";name=" + getNnnnnnnnnnnnnnnnnnnnnnname(); 3     Log.i("demo", msg); 4 } 5 private int getAaaaaaaaaaaaaaaaaaaaaaaaaaaAge() { 6     return age; 7 } 8 private String getNnnnnnnnnnnnnnnnnnnnnnname() { 9     return name;10 }

    (2)Constant

       作用:提取常量,将表达式中的值提取为常量。

       快捷键:Ctrl + Alt +C

       重构前:

1 public void testExtractConstant() {2   String filename = "sdcard";3 }

重构后:

1 public static final String SDCARD = "sdcard";2 public void testExtractConstant() {3   String filename = SDCARD;4 }

    (3)Filed

       作用:提取字段,将局部变量提取为全局变量。

       快捷键:Ctrl + Alt +F

       重构前:

1 public void testExtractField() {2    String name ="zhangsan";3 }

        重构后:

1 private final String string = "zhangsan";2 public void testExtractField() {3 }

    (4)Parameter

       作用:将局部变量提取为方法的参数。

       快捷键:Ctrl + Alt +P

       重构前:

1 public void testExtractParameter() {2     printName();3 }4 private void printName(){5     String name = "zhangsan";6     Log.i("demo","My name is:"+name);7 }

      重构后:

1 public void testExtractParameter() {2     printName("zhangsan");3 }4 private void printName(String name){5     Log.i("demo","My name is:"+ name);6 }

    (5)Functional Parameter ( 函数式参数 ) Ctrl + Alt + Shift + P

    (6)Parameter Object

       作用:将参数提取为一个对象。该功能主要是针对参数比较多的时候,将这些参数提取出来作为一个Bean实例传入。

       重构前:

1 private void testExtractParamObject() {2     String info = getInfo("zhangshan", 20, 180f);3 }4 private String getInfo(String name, int age, float height) {5     return "name=" + name + ";age=" + age + ";height=" + height;6 }

       重构后:

 1 private void testExtractParamObject() { 2     String info = getInfo(new Person("zhangshan", 20, 180f)); 3 } 4 private String getInfo(Person person) { 5     return "name=" + person.getName() + ";age=" + person.getAge() + ";height=" + person.getHeight(); 6 } 7 private static class Person { 8     private final String name; 9     private final int age;10     private final float height;11     private Person(String name, int age, float height) {12         this.name = name;13         this.age = age;14         this.height = height;15     }16     public String getName() {17         return name;18     }19     public int getAge() {20         return age;21     }22     public float getHeight() {23         return height;24     }25 }

    (7)Mehtod

       作用:提取为方法

       快捷键:Ctrl + Alt +M

       重构前:

1 public void testExtractMethod() {2     List nameList = new ArrayList<>();3     nameList.add("zhangshan");4     nameList.add("lisi");5     nameList.add("wangwu");6     int size = nameList.size();7 }

鼠标光标选中第2~5行后执行该重构方法

        重构后:

 1 public void testExtractMethod() { 2     List nameList = getNameList(); 3     int size = nameList.size(); 4 } 5 @NonNull 6 private List getNameList() { 7     List nameList = new ArrayList<>(); 8     nameList.add("zhangshan"); 9     nameList.add("lisi");10     nameList.add("wangwu");11     return nameList;12 }

    (8)Type Parameter

    (9)Method Object

       作用:将该选中的内容提取为一个方法,并提取到一个独立的类中。和“Method”很类似,不同的是提取的方法最后放在哪里。

       重构前:

1 public void testExtractMethod() {2     List nameList = new ArrayList<>();3     nameList.add("zhangshan");4     nameList.add("lisi");5     nameList.add("wangwu");6     int size = nameList.size();7 }

        重构后:

 1 public void testExtractMethod() { 2     List nameList = Utils.invoke(); 3     int size = nameList.size(); 4 } 5 private static class Utils { 6     private static List invoke() { 7         List nameList = new ArrayList<>(); 8         nameList.add("zhangshan"); 9         nameList.add("lisi");10         nameList.add("wangwu");11         return nameList;12     }13 }

    (10)Delegate

       作用:提取为一个代理类。

       重构前:

1 public class RefactorTest{2 3     public void testExtractInterface() {4         System.out.print("testExtractInterface");5     }6 }

       重构后:

 1 public class RefactorTestDelegate { 2     public RefactorTestDelegate() { 3     } 4  5     public void testExtractInterface() { 6         System.out.print("testExtractInterface"); 7     } 8 } 9 10 public class RefactorTest{11 12     private final RefactorTestDelegate refactorTestDelegate = new RefactorTestDelegate();13 14     public void testExtractInterface() {15         refactorTestDelegate.testExtractInterface();16     }17 }

    (11)Interrface

       作用:提取为接口。

       重构前:

1 public class RefactorTest {2 3     public void testExtractInterface() {4         System.out.print("testExtractInterface");5     }6 }

public修饰的方法才可以被提取到接口中。

        重构后: 

 1 interface IRefactorTest { 2     void testExtractInterface(); 3 } 4  5 public class RefactorTest implements IRefactorTest { 6  7     @Override 8     public void testExtractInterface() { 9         System.out.print("testExtractInterface");10     }11 }

    (12)Superclass

       作用:将指定内容提取到父类中。

       重构前:

1 private void testExtractSupperclass() {2       testSuper();3 }4 5 public void testSuper() {6      System.out.print("testSuper");7 }

       重构后:

 1 //=======RefactorTest extends RefactorTestBase======= 2 private void testExtractSupperclass() { 3     testSuper(); 4 } 5  6 class RefactorTestBase { 7     public void testSuper() { 8         System.out.print("testSuper"); 9     }10 }

    (13) Style

       作用:将属性提取为Style。该项只有当鼠标停留在布局文件中时才会出现。

       重构前:

1 <Button2     android:id="@+id/btn_handler_demo"3     android:layout_width="wrap_content"4     android:layout_height="wrap_content"5     android:text="handler" />

       

       重构后:

1 <Button2     android:id="@+id/btn_handler_demo"3     android:text="handler"4     style="@style/testStyle" />

 styles.xml

1 <?xml version="1.0" encoding="utf-8"?>2 <resources>3     <style name="testStyle">4         <item name="android:layout_width">wrap_contentitem>5         <item name="android:layout_height">wrap_contentitem>6     style>7 resources>

    (14)Layout

       作用:提取为布局文件。这一项也是需要在鼠标停留在布局文件中时才会出现。

 1 <LinearLayout 2     android:layout_width="match_parent" 3     android:layout_height="wrap_content" 4     android:orientation="horizontal"> 5     <Button 6         android:id="@+id/btn_handler_demo" 7         android:layout_width="wrap_content" 8         android:layout_height="wrap_content" 9         android:text="handler" />10     <Button11         android:id="@+id/btn_broadcast_demo"12         android:layout_width="wrap_content"13         android:layout_height="wrap_content"14         android:text="Broadcast" />15     <Button16         android:id="@+id/btn_bright_demo"17         android:layout_width="wrap_content"18         android:layout_height="wrap_content"19         android:text="Bright" />20     <Button21         android:id="@+id/btn_service_demo"22         android:layout_width="wrap_content"23         android:layout_height="wrap_content"24         android:text="Service" />25 LinearLayout>

       重构后:

<include layout="@layout/testlayout" />

testlayout.xml

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     xmlns:tools="http://schemas.android.com/tools" 4     android:layout_width="match_parent" 5     android:layout_height="wrap_content" 6     android:orientation="horizontal" 7     tools:showIn="@layout/activity_main"> 8  9     <Button10         android:id="@+id/btn_preference_demo"11         android:layout_width="wrap_content"12         android:layout_height="wrap_content"13         android:text="Preference" />14 15     <Button16         android:id="@+id/btn_file_demo"17         android:layout_width="wrap_content"18         android:layout_height="wrap_content"19         android:text="File" />20 21     <Button22         android:id="@+id/btn_anim_demo"23         android:layout_width="wrap_content"24         android:layout_height="wrap_content"25         android:text="Anim" />26 27     <Button28         android:id="@+id/btn_customview_demo"29         android:layout_width="wrap_content"30         android:layout_height="wrap_content"31         android:text="CustomView" />32 LinearLayout>

 

12、Inline

       作用:转换为内联、方法链形式的调用。

       快捷键:Ctrl + Alt +N

       重构前:

1 private void testInline() {2     int a = 100;3     int b = 200;4     System.out.print(add(a, b));5 }6 private int add(int a, int b) {7     System.out.print("a=" + a + ";b=" + b);8     return a*2 + b*3;9 }

       重构后: 

1 private void testInline() {2     int a = 100;3     int b = 200;4     System.out.print("a=" + a + ";b=" + b);5     System.out.print(a * 2 + b * 3);6 }

原先需要调用一个方法,重构后直接把该方法中的代码给复制过来了。因为上面选中的是内联所有的,并且删除该方法,所以add方法也就被删除了。

 

13、Find and Replace Code Duplicates

 

14、Invert Boolean

       作用:转换Boolean值,将当前false/true的值进行转化为相反的值。

       重构前:

1 private boolean isEmpty(String str) {2     if (str != null && str.length() == 0) {3         return false;4     }5     return true;6 }

       重构后:

1 private boolean isNotEmpty(String str) {2     if (str != null && str.length() == 0) {3         return true;4     }5     return false;6 }

 

15、Pull Members Up

       作用:将子类的成员上移到父类中。

       重构前:

 1 public class RefactorBase { 2  3 } 4  5 public class RafactorSub extends RefactorBase { 6     int age = 10; 7  8     public void printSub() { 9         System.out.print(age);10     }11 }

       重构后:

 1 public class RefactorBase { 2     int age = 10; 3     public void printSub() { 4         System.out.print(age); 5     } 6 } 7  8 public class RafactorSub extends RefactorBase { 9 10 }

 

16、Push Members Down

       作用:将父类中的成员下移到子类中,正好是“Pull Members Up”的反向操作。

       重构前:

 1 public class RefactorBase { 2     int age = 10; 3     public void printSub() { 4         System.out.print(age); 5     } 6 } 7   8 public class RafactorSub extends RefactorBase { 9  10 }

       重构后:

1 public class RefactorBase {2 3 }4 public class RafactorSub extends RefactorBase {5     int age = 10;6     public void printSub() {7         System.out.print(age);8     }9 }

 

17、Use Interface Where Possible

 

18、Replace Inheritance with Delegation

       作用:使用代理替代继承。在java中,提倡使用组合,而不是继承。

       重构前:

 1 public abstract class AbsClass { 2     public abstract void print(); 3 } 4  5 public class ClassWrapper extends AbsClass { 6     @Override 7     public void print() { 8         System.out.print("print"); 9     }10 }11 12 private void testReplaceInheritanceWithDelegation() {13     new ClassWrapper().print();14 }

        重构后:

 1 public abstract class AbsClass { 2     public abstract void print(); 3 } 4  5 public class ClassWrapper { 6     private final ClassImpl absClass = new ClassImpl(); 7  8     public void print() { 9         absClass.print();10     }11 12     private class ClassImpl extends AbsClass {13         @Override14         public void print() {15             System.out.print("print");16         }17     }18 }19 20 public class RefactorTest {21     private void testReplaceInheritanceWithDelegation() {22         new ClassWrapper().print();23     }24 }

 这一部分有点像Android中Context,ContextWrapper,ContextImpl类之间的关系。

 

19、Remove Middleman

       作用:移除中间人,其实就是移除中间过程。

       重构前:

 1 public class RefactorTest { 2  3     private void testRemoveMiddleMan() { 4         BookManager bookManager = new BookManager(); 5         bookManager.addBook("java"); 6     } 7  8     public static class BookManager { 9         private List mBookList = new ArrayList<>();10 11         private void addBook(String bookName) {12             mBookList.add(bookName);13         }14     }15 }

       重构后:

 1 public class RefactorTest { 2  3     private void testRemoveMiddleMan() { 4         BookManager bookManager = new BookManager(); 5         bookManager.getmBookList().add("java"); 6     } 7  8     public static class BookManager { 9         private List mBookList = new ArrayList<>();10 11         public List getmBookList() {12             return mBookList;13         }14     }15 }

对比重构前和重构后会发现,添加book这个动作,从由BookManager的addBook方法来执行,变成了直接有mBookList来执行了。这个addBook就是这个MiddleMan,显得多余,可以优化掉。实际上优化后就变成一个inline方式了,可以对比前面讲到的“Inline”。

 

20、Wrap Method Return Value

       作用:封装返回值

 1 public class RefactorTest { 2  3     private void testWrapReturnValue() { 4         String name = getName(); 5     } 6  7     private String getName() { 8         return "zhangsan"; 9     }10 }

       重构后:

 1 public class RefactorTest { 2  3     private void testWrapReturnValue() { 4         String name = getName().getValue(); 5     } 6  7     private Person getName() { 8         return new Person("zhangsan"); 9     }10 11     public class Person {12         private final String value;13 14         public Person(String value) {15             this.value = value;16         }17 18         public String getValue() {19             return value;20         }21     }22 }

 

21、Convert Anonymous to Inner

       作用:将匿名内部类转为内部类。

       重构前:

1 private void testConvertAnonymousToInner(){2     view.setOnClickListener(new View.OnClickListener() {3         @Override4         public void onClick(View v) {5         }6     });7 }

        重构后:

 1 public class RefactorTest{ 2  3     View view; 4     private void testConvertAnonymousToInner(){ 5         view.setOnClickListener(new MyOnClickListener()); 6     } 7  8     private static class MyOnClickListener implements View.OnClickListener { 9         @Override10         public void onClick(View v) {11 12         }13     }14 }

 

22、Encapsulate Fields

       作用:封装字段,用于生成Getter/Setter

       重构前:

1 public String name = "zhangsan";2 private void testEncapsulateFields() {3     System.out.println(name);4 }

 通过该对话框,可以选择要封装的字段,设置修饰符等。默认选择时,name字段的修饰符从public变成了private,这也就避免了外部类通过实例直接访问它。

       重构后:

 1 private String name = "zhangsan"; 2 private void testEncapsulateFields() { 3     System.out.println(getName()); 4 } 5 public String getName() { 6     return name; 7 } 8 public void setName(String name) { 9     this.name = name;10 }

 

23、Replace Temp With Query

 

24、Replace Constructor with Factory Method

       作用:将构造方法替换为工厂方法

       重构前:

 1 public class MyClass { 2  3     private String title; 4     private String message; 5     private String sure; 6     private String cancel; 7  8     public MyClass(String title, String message, String sure, String cancel) { 9         this.title = title;10         this.message = message;11         this.sure = sure;12         this.cancel = cancel;13     }14 }15 16 public class RefactorTest {17     private void testReplaceConstructorWithFactory(Context context) {18         MyClass myClass = new MyClass("title", "message", "sure", "cancle");19     }20 }

       重构后:

 1 public class MyClass { 2  3     private String title; 4     private String message; 5     private String sure; 6     private String cancel; 7  8     private MyClass(String title, String message, String sure, String cancel) { 9         this.title = title;10         this.message = message;11         this.sure = sure;12         this.cancel = cancel;13     }14 15     public static MyClass createMyClass(String title, String message, String sure, String cancel) {16         return new MyClass(title, message, sure, cancel);17     }18 }19 20 public class RefactorTest {21     private void testReplaceConstructorWithFactory(Context context) {22         MyClass myClass = MyClass.createMyClass("title", "message", "sure", "cancle");23     }24 }

原先public修饰的构造函数,已经变成private了,MyClass类只能通过工厂方法来获取实例,而无法再直接new了。

 

25、Replace Constructor with Builder

       作用:将构造方法替换为Builder方式

       重构前:

 1 public class RefactorTest{ 2     private void testReplaceConstructorWithBuilder(Context context){ 3         MyDialog dialog =  new MyDialog(context,"title","message","sure","cancle"); 4     } 5 } 6  7 public class MyDialog extends Dialog { 8     private String title; 9     private String message;10     private String sure;11     private String cancel;12     public MyDialog(@NonNull Context context) {13         super(context);14     }15     public MyDialog(Context context, String title, String message, String sure, String cancel) {16         super(context);17         this.title = title;18         this.message = message;19         this.sure = sure;20         this.cancel = cancel;21     }22 }

 

重构后:

 1 public class RefactorTest { 2     private void testReplaceConstructorWithBuilder(Context context) { 3         MyDialog dialog = new MyDialogBuilder() 4                 .setContext(context) 5                 .setTitle("title") 6                 .setMessage("message") 7                 .setSure("sure") 8                 .setCancel("cancle") 9                 .createMyDialog();10     }11 }12 13 public class MyDialogBuilder {14     private Context context;15     private String title;16     private String message;17     private String sure;18     private String cancel;19 20     public MyDialogBuilder setContext(Context context) {21         this.context = context;22         return this;23     }24 25     public MyDialogBuilder setTitle(String title) {26         this.title = title;27         return this;28     }29 30     public MyDialogBuilder setMessage(String message) {31         this.message = message;32         return this;33     }34 35     public MyDialogBuilder setSure(String sure) {36         this.sure = sure;37         return this;38     }39 40     public MyDialogBuilder setCancel(String cancel) {41         this.cancel = cancel;42         return this;43     }44 45     public MyDialog createMyDialog() {46         return new MyDialog(context);47     }48 }

看到这里,我们应该能够联想到AlertDialog类中的Builder了。将构造函数的形式,转变为了建造者模式的形式,这样不会拘泥于构造函数的参数个数,参数类型的限制,从而灵活设置属性。 

 

26、Generify

       作用:泛型重构,自动添加泛型的参数。

       重构前:

1 private void testGenerify() {2     List list = new ArrayList();3     list.add("one");4     list.add("two");5     list.add("three");6 }

       重构后:

1 private void testGenerify() {2     List list = new ArrayList();3     list.add("one");4     list.add("two");5     list.add("three");6 }

27、Migrate

28、Internationalize(国际化)

 

29、Remove Unused Resources

       作用:一直不用的资源

       示例:下图中1.jpg是一个没有被应用的文件。

 

 

在执行该重构方法后,1.jpg就被删除了。

 

 

参考:https://www.jianshu.com/p/f8cb51bc8e19

更多相关文章

  1. Unity3D游戏开发之Unity与Android交互调用研究
  2. libgdx中延迟加载资源文件
  3. Android(安卓)访问 .net C#写的webservice
  4. Android真正的静默安装
  5. Android中实现IPC的几种方式详细分析及比较
  6. android 解决listview.notifyDataSetChanged刷新时Imageloader加
  7. 【Android】PopupWindow中使用listview,listview的点击事件响应很
  8. 开始使用Android(安卓)Sutdio(四)Android(安卓)Studio的配置
  9. Android的schedule、AlarmService、Timer定时器机制

随机推荐

  1. PHP+jQuery实现中国地图热点数据统计展示
  2. PHP钩子机制原理及详解
  3. PHP生成有背景的二维码图片(代码示例)
  4. 分享学好PHP的几个重要心得
  5. Pimple运行流程浅析(PHP容器)
  6. 在PHP中进行会话处理(代码详解)
  7. 利用php实现读取excel中的图片
  8. PHP中经典的四大排序算法
  9. 一文搞懂PHP类和对象、抽象类、接口
  10. 如何通过imagick让PHP生成PSD文件缩略图(