谢真平
【文章摘要】
在Visual Studio 2005中新增了重构功能,虽然目前还不能和Resharper、Eclipse相比。但对于使用.Net的开发人员来说也是一个福音,重构是很多开发人员不愿做的事,因为看不到明显的实效,而使用此工具为我们节约时间,提高效率,可以让我们更加喜爱和经常的重构,对软件代码的长期维护很有益处。另外,这些重构方法其实并不只在重构的时候用,我们在常规代码编写中有时也用武之路。这次在对ADC的BOSS接口机代码重构当中,我用到了此工具,感觉不错,借此给还没使用过的同事分享下,也希望与其他同事共同探讨。
【关键词】
重构 VisualStudio2005 代码维护 效率
(一)功能预览
Visual Studio 2005的用户界面有一个“重构”菜单来显示操作。(见表1)也可使用快捷键。
表1 重构操作
操 作 |
描 述 |
重命名 |
重命名操作在整个应用程序中对一个符号进行重命名,例如一个变量或方法名称 |
提取方法 |
提取方法操作创建一个封装选定代码的新方法 |
封装字段 |
封装字段操作创建对选定字段进行抽象的属性 |
提取接口 |
提取接口操作从一个类型中提取一个接口 |
将局部变量提升为参数 |
提升局部变量到参数操作提升一个局部变量到当前方法的一个参数 |
移除参数 |
移除参数操作从一个函数的参数列表中移除一个参数。调用函数的地方也跟着更新以反映参数的移除 |
重新排列参数 |
重排参数操作对一个函数的参数进行重排。调用函数的地方也跟着新的参数顺序进行更新 |
现在可能觉得这些描述有些生硬与抽象,下面跟着我一起看看:
(二)体验重构
【1】提取方法
当你编写了一个代码很长的方法,它包含一些复杂的算法集合。使它太大、太复杂,以至于其它成员或下一任代码维护者难以理解。因此,你需要把它拆分成多个小函数。这不仅会简化你的代码而且还能改进其易读和可维护性。"提取方法"选项正是适合这一工作。
<举例>
操作前:
public void TestMethod()
{
string a = "";
string b = "";
string c = "";
c = a + b;
}
我们用四句简单的语句表示方法中的多个复杂算法,现在假设我们要把后两句提成方法。
操作:(1)选中后两句;(2)选“提取方法”功能(3)在对话框中可修改新方法名
操作后:
public void TestMethod()
{
string a = "";
string b = "";
NewMethod(a, b);
}
private static void NewMethod(string a, string b)
{
string c = "";
c = a + b;
}
结果不错,它为我们完成了两件事情:
· 根据你的选择创建一个新的方法并且替换其中的所有选择的代码。
·创建新方法的调用来替换选择的行。生成的输入输出参数都非常自动化。
【2】重命名
我们有时要对一些标识符进行重命名,但这些代码由于调用的原因,可能散落在项目的多个地方,要全部修改完绝非易事。“重命名”可以帮你轻松完成。可重命名的内容包括字段、局部变量、方法、命名空间、属性和类型等标识符。还能更改注释。
操作方法:(1)光标移到要重命名的标识符上(2)选“重命名”功能(3)在对话框中输入新名称
这时系统会弹出预览框,它会为你显示所有涉及修改的文件名称及位置,单击文件名显示具体修改位置,让你心中有数。这个预览框在重构的多个操作中都会及时地显示,你就放心吧。保证操作后能编译通过。
【3】封装字段
我记得第一次在Eclipse中使用到这个功能时,非常高兴。同时又想:为什么Visual Studio 家族没有这个功能呢?果然,现在有了,这个功能在平常编程中都可以用到。但在使用时,你可能和我当初一样会遇到如下问题:提示:
Code Snippet titled [xxxxxxxxxxx] failed to load. Verify that refactoring snippets are recognized in the Code Snippet Manager and that the snippet files are valid on disk.
我当时不得其解,后来终于查到原因了,修正方法如下:
打开Code Snippet Manager(按Ctrl + K后接着按Ctrl + B ),然后选择要操作的语言(C#),用Add按钮导入两个默认的文件夹:Refactoring和Visual C#,这两个文件夹一般会在VS2005安装目录下的,如:C:"Program Files"Microsoft Visual Studio 8"VC#"Snippets"1033
操作方法:(1)光标移到要封装的字段上(2)选“封装字段”功能(3)在对话框中输入属性名称
<举例>
操作前:
string s;
操作后:
string s;
public string S
{
get { return s; }
set { s = value; }
}
【4】将局部变量提升为参数
有时,代码中某变量的取值位置发生改变,如由方法内部获取变为从外部传入。我们就得改本方法及上层调用者,非常的麻烦。使用此功能吧,将使你烦恼全无。
<举例>
操作前:
public void TestMethod()
{
string a = NewMethod();
}
private string NewMethod()
{
string s = "abc";
string t = s + "123";
return t;
}
我们将把string s = "abc";改变为由参数传进来,操作:(1)光标移到此行上(2)选“将局部变量提升为参数”功能
操作后:
public void TestMethod()
{
string a = NewMethod("abc");
}
private string NewMethod(string s)
{
string t = s + "123";
return t;
}
你看,不管是本方法还是它的调用者都自动修改了。另外,有两个相似的功能“移除参数”和“重新排列参数”,操作都差不多,本文就略去了。
【5】提取接口
随着系统功能的增强,代码复杂度增加,我们需要将某个类抽象为接口。这将影响到多个地方的修改。用此功能非常简单:
<举例>
操作前;
public class ClaseTest
{
public void A()
{
}
public void B()
{
}
public void C()
{
}
public void D()
{
}
}
假设我们要把ClaseTest提取为接口。操作:(1)光标移到类名上(2)选“提取接口”功能(3)在弹出的对话框中做三件事:修改接口名;修改接口文件名;选择要作为本接口的方法申明。
操作后:
public class ClaseTest : ConsoleServie.IClaseTest1
{
public void A()
{
}
public void B()
{
}
public void C()
{
}
public void D()
{
}
}
并且系统新增一个接口文件,内容如下(我没有选D方法):
using System;
namespace ConsoleServie
{
interface IClaseTest1
{
void A();
void B();
void C();
}
}
(三)小结
不管是Visual Studio 、Eclipse,还是其它的开发工具,随着他们的升级,都会提升或新增功能,希望我们都能利用好,为我们的工作服务,使我们编程工作更加快乐。