後編 Visual Studio 2017のリファクタリング機能:特集:Visual Studioで始めるリファクタリング(4/4 ページ)
変数レベル/メソッドレベル/型レベルでのリファクタリングを支援するために、Visual Studio 2017が提供している機能を取り上げる。
型レベルのリファクタリング
クラスやインタフェースなどの型に対するリファクタリングサポート機能は充実しているとは言いにくいが、それでも前編で紹介した「名前の変更」の他に、幾つか便利な機能が用意されている。
型をファイル名に、またはファイル名を型に同期する
例えばクラスのファイル名が「Class1.cs」で、そこに入っているクラスの名前が「Foo」だったとしよう(つまり、後からクラス名を変更した場合だ)。
そこでクラス名「Foo」の部分を指定して、リファクタリングサポート機能の[ファイル名を Foo.cs に変更]を選ぶと、簡単にファイル名を変更できる(次の画像)。逆に、[型の名前を Class1 に変更]を選べば、クラス名の方をファイル名に合わせて変更できる。
型を適切なファイルに移動する
例えば、「Foo.cs」ファイルの中に、「Foo」クラスの他に「FooKind」列挙体も定義したとする。後になって、この列挙体はやはり独立したファイルに置くべきだと考えを改めた場合、列挙体の名前「FooKind」の部分を指定して、リファクタリングサポート機能の[型を FooKind.cs に移動]を選ぶと、簡単に新しいファイルを作ってそこに移動できる(次の画像)。
このとき、新しく作られたファイルでは、名前空間のusing文も必要な分だけがきちんと記述される。
『インターフェイスの抽出』(Extract Interface)
この機能は、クラス定義からインタフェースを生成する。クラス名を指定して、リファクタリングサポート機能の[インターフェイスの抽出]を選ぶと、次の画像のようなダイアログが出てくる。
上のダイアログにはクラスのパブリックなメンバが全て列挙されているので、インタフェースに含めたくないメンバのチェックを外してから[OK]ボタンをクリックする。すると新しいファイルが作られて、そこにインタフェース定義が生成される(次のコードはこの機能を利用して、Fooクラスが持っていた3つのメソッドをインタフェース化したものだ)。
// リファクタリング前
// ファイル「Foo.cs」
namespace RefactoringSample
{
public class Foo
{
public string MethodA(string s) => s;
public string MethodB(string s) => s.ToUpperInvariant();
public string MethodC(string s) => s.ToLowerInvariant();
}
}
// ↓
// リファクタリング後
// 新しいファイル「IFoo.cs」
namespace RefactoringSample
{
public interface IFoo
{
string MethodA(string s);
string MethodB(string s);
}
}
// 元のファイル「Foo.cs」
namespace RefactoringSample
{
public class Foo : IFoo
{
public string MethodA(string s) => s;
public string MethodB(string s) => s.ToUpperInvariant();
public string MethodC(string s) => s.ToLowerInvariant();
}
}
ここでは、クラスに3つあるメソッドのうち、2つだけをインタフェースに切り出した。
リファクタリング後、「Foo」クラスは、ちゃんと「IFoo」インタフェースを実装した形に変わっている。
まとめ
今回はかなり駆け足ぎみではあったが、VS 2017のリファクタリングサポート機能を一通り紹介した。前回の名前の変更と併せて、ぜひ使ってみてほしい。初めのうちは、外的な振る舞いに変化がないかを確かめながら、慎重に。そして信用できると確信できた機能は、大胆に使っていこう。リファクタリング作業の効率が上がること、間違いなしである。
VS 2017のリファクタリングサポート機能だけでは物足りないと感じるようになったら、「ReSharper」などのサードパーティー製品を調べてみてほしい。どこをどのようにリファクタリングすべきかを考えるのは開発者の役目だが、実際のリファクタリング作業は可能な限り自動化したいものである。
Copyright© Digital Advantage Corp. All Rights Reserved.