Help us understand the problem. What is going on with this article?

Delphi IDE の便利な機能 - リファクタリング - 詳細

これは Delphi Advent Calendar 2019 の 7 日目の記事です

次の課題が現れた

「リファクタリングメニューの詳細な動き」というお題
まず、メニューの中身を見てみよう

メニューの中身

  • 移動
  • インターフェースの抽出
  • スーパークラスの抽出
  • メンバのプルアップ
  • メンバのプッシュダウン
  • 安全な削除
  • 変数のインライン化
  • フィールドの導入
  • 変数の導入
  • 名前の変更
  • 変数の宣言
  • フィールドの宣言
  • メソッドの抽出
  • リソース文字列の抽出
  • パラメータの変更
  • ユニットの検索

とある
それぞれどんな時に使うのか、どんな事ができるのかを確認してみた

移動

あ、このクラス作ったけど、他のユニット (名前空間) に移動したいというときに便利

例えば、VCL アプリケーションを作るじゃろ
クラスを定義するじゃろ
プロジェクトにユニットを追加するじゃろ
移動を実行するじゃろ
作ったクラスが追加したユニット側に移動するのじゃ
moveClass.gif
この例では、Unit3 に定義した THoge クラスが Unit4 側に移動します

ヘルプ - メンバを移動する

インターフェースの抽出

選択した 1 つ以上のクラスから新しいインターフェイスを作成します
選択したクラスには、生成されたインターフェースが追加されます

THoge = class の箇所にカーソルを置き(ナビゲーションツールバーの型の欄に該当するクラスが表示されている状態)で、メニューから [リファクタリング|インターフェースの抽出] を選択します
interface1.png

インターフェース名や、名前空間などを設定するダイアログが表示されます
interface2.png

[OK] ボタンを押すと、インターフェース (Ihoge) が生成され、選択したクラスにはインターフェースが追加されています
interface3.png

ちょっと残念なのは生成されたインターフェースが後ろに来てしまうので、エラーインサイトで未定義の識別子として検出されてしまう点

クラスとインターフェイスの関係は、ドキュメントの「インターフェイスの使用」を参照のこと

ヘルプ - インターフェースを抽出する

スーパークラスの抽出

選択したクラスから上位クラス( スーパークラス )を作成します。

インターフェースの抽出の時と同様に、THoge = class の箇所にカーソルを置き(ナビゲーションツールバーの型の欄に該当するクラスが表示されている状態)で、メニューから [リファクタリング|スーパークラスの抽出] を選択します
同様にダイアログが表示されます
super1.png

[OK] ボタンを押すと、スーパークラス (Shoge) が生成され、選択したクラス (Thoge) は、スーパークラスを継承する定義に変更されます
super2.png

ヘルプ - スーパークラスを抽出する

メンバのプルアップ

クラスのメンバ( フィールド、メソッド、プロパティ、イベント )を上位のスーパークラスに移動させます
仕様変更でクラスのメンバを上位クラスに移動させる時に使える

エラーインサイトにエラーがあると実行されないので注意

THoge クラスの hoge2 の

procedure Shoge.hoge2;
begin
end;

の箇所を選択して、メニューから [リファクタリング|メンバのプルアップ] を選択します
pullup1.png

選択したメンバのプルアップを行うためのダイアログが表示されます
pullup2.png

[OK]ボタンを押し実行すると、hoge2 は上位のスーパークラス Shoge に移動します
pullup3.png

ヘルプ - メンバのプルアップおよびプッシュダウン

メンバのプッシュダウン

プルアップの反対で、クラスのメンバ( フィールド、メソッド、プロパティ、イベント )を継承先のクラスに移動させます
仕様変更でクラスのメンバを継承クラスへ移動させる時に使える

エラーインサイトにエラーがあると実行されないので注意

Shoge クラスの hoge2 の

procedure Shoge.hoge2;
begin
end;

の箇所を選択して、メニューから [リファクタリング|メンバのプルダウン] を選択します
pushdown1.png

選択したメンバのプルダウンを行うためのダイアログが表示されます
pushdown2.png

[OK]ボタンを押し実行すると、hoge2 は継承されたクラス THoge に移動します
pushdown3.png

ヘルプ - メンバのプルアップおよびプッシュダウン

安全な削除

削除したい要素がコードの中で使われていないかを検索して、削除を実行します

まず、削除をしたい要素を選択して、メニューから [リファクタリング|安全な削除] を選択します
deleteValiable1.png

安全な削除のダイアログが表示されます
この例では、他にこの要素を使用しているところはないので、このまま [削除] をクリックします
deleteValiable2.png

要素の削除、および定義の削除が行われます
deleteValiable3.png

ヘルプ - 安全に削除する

変数のインライン化

例えば以下の例

var 
  i: Integer;
begin
  i := 10;
  ShowMessage('変数のインライン化:' + IntToStr(i));
end;

のようなコードは、

begin
  ShowMessage('変数のインライン化:' + IntToStr(10));
end;

と同じです。
変数のインライン化では、このような冗長なコードを検索し、更新することができます。

実際の手順ですが、ローカル変数の箇所を選択します
以下の例の場合は、変数 i を選択するか、i の直後にキャレットを置くかのどちらかになります
選択またはキャレットを置いたら、IDE のメニューから [リファクタリング|変数のインライン化] を選択します
インライン化のダイアログが表示されます
inline2.png

[OK] ボタンを押すと、変数の宣言が削除され、コード側に変数の値が埋め込まれます
inline3.png

ヘルプ - 変数のインライン化

フィールドの導入

var で変数を定義したんだけど、他でも参照したいから クラスのフィールドとして定義して使用したいという時に使える機能
フィールドを導入した際のデータ型は、変数として定義されたときの型をそのまま使用します

実際の手順ですが、以下のようなコードがあります
FInsert1.png

ローカル変数の箇所を選択します
この例の場合は、変数 i を選択するか、i の直後にキャレットを置くかのどちらかになります
選択またはキャレットを置いたら、IDE のメニューから [リファクタリング|フィールドの導入] を選択します
フィールドの導入のダイアログが表示されますので、フィールドとして定義する際の名前や可視性(private, publicなど)を設定します
また、初期値を設定したい場合は初期値を設定します
FInsert2.png

[OK] ボタンを押すと、フィールド定義が行われ、選択したブロックの変数は置き換わり(この例では定義が削除されます)
他のブロックで同じ名前の変数を使用している箇所は置き換わりません
(AI が搭載されていないので)それがフィールドなのか、変数で使用されるのかが判断できないからです
FInsert3.png

ヘルプ - フィールドの導入

変数の導入

クラスのフィールドを使用しているんだけど、やっぱり変数で処理を行ないたいというときに使える機能
変数を導入した際のデータ型は、フィールドとして定義されたときの型をそのまま使用します

実際の手順ですが、以下のようなコードがあります
フィールドの箇所を選択します
以下の例の場合は、フィールド i を選択するか、i の直後にキャレットを置くかのどちらかになります
選択またはキャレットを置いたら、IDE のメニューから [リファクタリング|変数の導入] を選択します
vInsert1.png

変数の導入のダイアログが表示されますので、変数として定義する際の名前を設定します
vInsert2.png

[OK] ボタンを押すと、変数の定義が行われ、選択したブロックのフィールドは、新しい変数を使用したものに置き換わります
vInsert3.png

ヘルプ - 変数の導入

名前の変更

たぶん一番使用するであろう機能
こちらは以前に説明しているので、Delphi IDE の便利な機能 - 名前のリファクタリング の記事をご覧ください

変数の宣言

コードは書いたけど変数として宣言しようか、フィールドとして宣言しようか....
うん、変数、君に決めた!
というときに使える機能

実際の手順ですが、以下のようなコードがあります
コード内の hoge1 を選択して、IDE のメニューから [リファクタリング|変数の宣言] を選択します
vSengen1.png

新規変数の宣言のダイアログが表示されますので、変数として定義する際のデータ型を設定します
初期値の設定が必要な場合は、値の設定にチェックをつけて、初期値を入力します
vSengen2.png

[OK] ボタンを押すと、変数の宣言が行われます
vSengen3.png

同様に hoge2 も選択して、IDE のメニューから [リファクタリング|変数の宣言] を行います
vSengen4.png

ヘルプ - 変数の宣言

フィールドの宣言

コードは書いたけど変数として宣言しようか、フィールドとして宣言しようか....
うん、フィールド、君に決めた!
というときに使える機能

実際の手順ですが、以下のようなコードがあります
コード内の hoge1 を選択して、IDE のメニューから [リファクタリング|フィールドの宣言] を選択します
FSengen1.png

新規フィールドの宣言のダイアログが表示されますので、フィールドとして定義する際のデータ型を設定します
またアクセス制御 (private, public など) を設定します。
FSengen2.png

[OK] ボタンを押すと、フィールドの宣言が行われます
FSengen3.png

hoge2 は区別するため変数として宣言をしてみました
FSengen4.png

ヘルプ - フィールドの宣言

メソッドの抽出

コード内のココの部分、他のところでも使うからメソッドにしておくと便利かな?と思った時に使える機能
選択した箇所を新たなメソッドとして抽出して定義し、選択した箇所をそのメソッドで置き換えます

あくまで新たなメソッドとして抽出するだけなので、パラメータの定義は行われないことに注意
パラメータを渡す場合は、この後、リファクタリングのパラメータの変更で修正を行う必要があります

この例では hogehoge1 := 0; を他でも使用するからメソッドとして抽出しています
まず該当の hogehoge1 := 0; を選択して、メニューから [リファクタリング|メソッドの抽出] を選択します
method1.png

メソッドの抽出ダイアログが現れます
デフォルトの ExtractedMethod の名前を newMethod に書き換えて [OK] をクリックします
method2.png

メソッドとして抽出され、必要な定義や、置き換えが行われます
method3.png

ヘルプ - メソッドの抽出

リソース文字列の抽出

コード内に文字列リテラルを書くということはよくありますが、修正時にいちいちコードを探して修正するのはめんどくさい
これを使うと、文字列リテラルを抽出してリソース文字列として定義してくれる

以下の例は、ShowMessage に記述されている文字列リテラルを取り出して、自動的に resousestring にリソース文字列として定義するというものです
resourceString.gif

ヘルプ - リソース文字列の抽出

パラメータの変更

メソッドの抽出のところでちらっと出てきましたが、定義されているメソッドのパラメータを変更したいときに使用します

実際の手順ですが、以下のようなコードがあります
コード内の hoge1 を選択、または hoge1 の直後にキャレットを置きます
IDE のメニューから [リファクタリング|パラメータの変更] を選択します
paramChange1.png

パラメータの変更のダイアログが表示されますので、新しいパラメータを追加するのであれば [追加] のボタンを押します
paramChange2.png

パラメータ名、データ型、パラメータの型を指定します
paramChange3.png

[OK] ボタンを押すと、パラメータが追加されます
更に追加するのであれば、再度 [追加] ボタンを、内容の編集を行うのであれば [編集] ボタンを、削除するのであれば [削除] ボタンをおして、定義するパラメータを編集します
paramChange4.png

編集が終わったら、[OK]ボタンを押します
宣言側、実装側、共に変更した内容が反映されます
paramChange5.png

ヘルプ - パラメータの変更

ユニットの検索

コードで別ユニット内のクラスなどを使う場合には uses 句に宣言されているユニットを追加する必要がありますが、あれあれ?どのユニットだったっけ?というときに使える機能

実際の手順ですが、以下のようなコードがあります
コード内の Form2 を選択します
IDE のメニューから [リファクタリング|ユニットの検索] を選択します
unitSearch1.png

ユニットの検索が行われ、候補が表示されます
該当する候補を選択して、インターフェースまたは実装として追加するかを選択します
unitSearch2.png

[OK] ボタンを押すと、検索して見つかったユニットの参照定義が追加されます
unitSearch3.png

ヘルプ - ユニットの検索

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした