Extract重構

2018-10-22 11:06 更新

Extract重構

IntelliJ IDEA提供各種Extract重構,以引入?yún)?shù),變量,常量,字段,方法和函數(shù)。要運行任何這些重構,請選擇要重構的表達式并選擇:Refactor|提取|<target>。您可以選擇整個表達式或將光標放在其中的任何位置,IntelliJ IDEA將幫助您進行選擇。

Extract Parameter

使用Extract Parameter(提取參數(shù))重構將函數(shù)調(diào)用中的表達式替換為參數(shù)。IntelliJ IDEA將相應地更新聲明和函數(shù)調(diào)用。新參數(shù)的默認值可以在函數(shù)體內(nèi)初始化或通過函數(shù)調(diào)用傳遞。

假設您在函數(shù)calculate_sum(i)中有一段硬編碼1的代碼。使用Extract Parameter重構,您可以使用i2參數(shù)替換此硬編碼1。新i2參數(shù)可以作為可選項或根據(jù)需要提取。

示例1:提取可選參數(shù)

提取新參數(shù)i2作為可選參數(shù)。新參數(shù)在主體calculate_sum(i)中初始化,并且show_sum()中calculate_sum(i)調(diào)用不會更改。

function calculate_sum(i) {
    alert('Adding ' + 1 + ' to ' + i);
    return  1 + i;
}

function show_sum() {
    alert('Result: ' + calculate_sum(5));
}
function calculate_sum(i, i2) {
    i2 = i2 || 1;
    alert('Adding ' + i2 + ' to ' + i);
    return i2 + i;
}

function show_sum() {
    alert('Result: ' + calculate_sum(5));
}

示例2:提取所需參數(shù)

提取新參數(shù)i2作為必需參數(shù),相應地更改show_sum()中calculate_sum(i)調(diào)用。

function calculate_sum(i) {
    alert('Adding ' + 1 + ' to ' + i);
    return 1 + i;
}

function show_sum() {
    alert('Result: ' + calculate_sum(5));
}
function calculate_sum(i, i2) {
    alert('Adding ' + i2 + ' to ' + i);
    return i2 + i;
}

function show_sum() {
    alert('Result: ' + calculate_sum(5, 1));
}

提取參數(shù)的操作如下:

  1. 在編輯器中,將光標放在要轉換為參數(shù)的表達式中,然后按Ctrl+Alt+P,或在上下文菜單或主菜單上選擇:Refactor|提取|參數(shù)。
  2. 如果在當前光標位置中檢測到多個表達式,請在“表達式”列表中選擇所需的表達式。
    ws_js_extract_parameter_select_expression.png
  3. 如果找到多個選定表達式,請選擇“僅替換此事件”或“找到多個匹配項”彈出菜單中的“替換所有匹配項”。
    ws_js_extract_parameter_multiple_occurrences.png
    最后,出現(xiàn)用于配置重構的彈出窗口。
    ws_js_extract_parameter_specify_parameter_name_and_type.png
  4. 選擇Generate JSDoc以生成JSDoc注釋塊。如果您需要指定自定義默認參數(shù)值,這可能會有所幫助。從JSDoc官方網(wǎng)站了解更多信息。
  5. 選擇新參數(shù)的類型(可選或必需)并指定其默認值(如果適用):
    • 如果選中“可選參數(shù)”復選框,則將使用函數(shù)體中的默認值初始化該參數(shù)。
    • 如果清除“可選參數(shù)”復選框,則默認參數(shù)值將通過現(xiàn)有函數(shù)調(diào)用傳遞。所有函數(shù)調(diào)用都將根據(jù)新的函數(shù)簽名進行更改,并且參數(shù)初始化將添加到函數(shù)體中。
    最初,IntelliJ IDEA接受調(diào)用重構作為默認值的表達式。在大多數(shù)情況下,您無需更改它。如果仍然需要,請以格式@param <parameter name> - <default value>在JSDoc注釋中指定另一個默認值。
  6. 通過在彈出列表中雙擊建議的參數(shù)名稱,或者在文本框中使用紅色畫布指定自定義名稱,接受其中一個建議的參數(shù)名稱。準備好后按“Enter”。
    ws_js_extract_parameter_result.png
    另請注意,在ES6代碼中,將應用新的默認函數(shù)參數(shù)語法function calculate_sum(i, i2 = 1) 而不是i2 = i2 || 1;。從https://developer.mozilla.org網(wǎng)站了解有關默認函數(shù)參數(shù)的更多信息 。

選擇重構模式:

您可以如上所述在編輯器中(在in-place模式下)提取參數(shù), 或使用“提取參數(shù)(Extract Parameter )”對話框。這兩種方法相似,區(qū)別如下:

  • 預覽重構的結果。在對話框中,可以單擊“預覽”并在“查找”工具窗口的專用選項卡中檢查預期的更改。在in-place模式下,此功能不可用。
  • 指定默認參數(shù)值。在對話框中,IntelliJ IDEA會在“值”字段中建議默認參數(shù)值,您可以在其中接受建議或指定其他值。在in-place模式下,IntelliJ IDEA將調(diào)用重構的表達式視為默認參數(shù)值。要指定另一個值,您必須使用JSDoc注釋塊。

默認情況下,IntelliJ IDEA在in-place模式下運行Extract Parameter重構。要使用“提取參數(shù)”對話框,請在“設置/首選項”對話框(Ctrl+Alt+S)中單擊:編輯器|常規(guī)。在打開的“常規(guī)”頁面上,清除“重構”區(qū)域中的“啟用in-place模式”復選框。

Extract Variable

使用Extract Variable(提取變量)重構將表達式替換為函數(shù)范圍的變量(var),塊范圍的變量(let)或常量。這種重構使您的源代碼更易于閱讀和維護。它還可以幫助您避免使用硬編碼常量,而無需對其值或目的進行任何解釋。

假設您在return語句中有一個帶有部分硬編碼表達式的函數(shù):

Parenizor.method('toString', function ()) {
    return '(' + this.getValue() + ')';
}

使用Extract Variable重構,您可以使用變量替換'(' + this.getValue() + ')'表達式,例如string。提取變量的范圍取決于其聲明(var或let)中使用的語句以及聲明新變量的上下文(函數(shù)內(nèi)部或外部)。

示例1:使用let語句聲明提取塊范圍的變量

從return語句中的'(' + this.getValue() + ')'表達式中提取變量。新變量使用let語句在Parenizor.method('toString', function ())內(nèi)部聲明。 


Parenizor.method('toString', function ()) {
    return '(' + this.getValue() + ')';
}


Parenizor.method('toString', function ()) {
    let string = '(' + this.getValue() + ')';
    return string;
}

示例2:提取變量并在任何函數(shù)外聲明它

變量appName從navigator.appName表達式中提取并在任何函數(shù)之外使用var語句聲明。


var browserName = "N/A";
if (navigator.appName.indexOf("Netscape") != -1) {
    browserName = "NS";
} else if (navigator.appName.indexOf("Microsoft") != -1) {
    browserName = "MSIE";
} else if (navigator.appName.indexOf("Opera") != -1) {
    browserName = "O";
}


var browserName = "N/A";
var appName = navigator.appName;
if (appName.indexOf("Netscape") != -1) {
    browserName = "NS";
} else if (appName.indexOf("Microsoft") != -1) {
    browserName = "MSIE";
} else if (appName.indexOf("Opera") != -1) {
    browserName = "O";
}

提取變量的操作如下所示:

  1. 在編輯器中,選擇要轉換為變量的表達式,然后按Ctrl+Alt+V,或在上下文菜單或主菜單上選擇:Refactor |提取|變量。
  2. 如果在當前光標位置中檢測到多個表達式,請在“表達式”列表中選擇所需的表達式。
    ws_js_refactoring_extract_variable_inplace_select_expression.png
  3. 如果找到多個選定表達式,請選擇“僅替換此事件”或“找到多個匹配項”彈出菜單中的“替換所有匹配項”。
    ws_js_refactoring_extract_variable_inplace_multiple_occurrences.png
    最后,出現(xiàn)用于配置重構的彈出窗口。
  4. 在彈出菜單中,選擇要在新變量聲明中使用的語句:
    • 選擇var以引入函數(shù)范圍的變量。
    • 選擇let以引入塊范圍的變量,請參閱上面的示例2。
    • 選擇const來引入常量。
    ws_js_refactoring_extract_variable_inplace_choose_scope_type.png
  5. 通過在彈出列表中雙擊建議的變量名稱或在文本框中指定自定義名稱來接受其中一個建議變量名稱。準備好后按“Enter”。

選擇重構模式

您可以如上所述在編輯器中(在in-place模式下)提取變量, 或使用“提取變量”對話框。默認情況下,IntelliJ IDEA在in-place模式下運行Extract Variable重構。要使用“提取變量”對話框,請在“設置/首選項”對話框(Ctrl+Alt+S)中單擊:編輯器|常規(guī)。在打開的“常規(guī)”頁面上,清除“重構”區(qū)域中的“啟用in-place模式”復選框。

Extract Field

在Extract Field重構宣布一個新的字段,并使用選定的表達對其進行初始化。原始表達式將替換為字段的用法。

在下面的示例中,提取相同的_calcArea字段。這些示例說明了初始化提取字段的三種不同方法。

示例1:在封閉方法中初始化提取的字段


class Rectangle {
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }

    get area() {
        return this.calcArea();
    }

    calcArea() {
        return this.height * this.width;
    }
}


class Rectangle {
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }

    _calcArea;

    get area() {
        this._calcArea = this.calcArea();
        return this._calcArea;
    }

    calcArea() {
        return this.height * this.width;
    }
}

示例2:提取的字段在其聲明中初始化


class Rectangle {
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }

    get area() {
        return this.calcArea();
    }

    calcArea() {
        return this.height * this.width;
    }
}


class Rectangle {
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }

    _calcArea = this.calcArea();

    get area() {
        return this._calcArea;
    }

    calcArea() {
        return this.height * this.width;
    }
}

示例3:提取的字段在類的構造函數(shù)中初始化


class Rectangle {
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }

    get area() {
        return this.calcArea();
    }

    calcArea() {
        return this.height * this.width;
    }
}


class Rectangle {
    constructor(height, width) {
        this._calcArea = this.calcArea();
        this.height = height;
        this.width = width;
    }

    _calcArea;

    get area() {
        return this._calcArea;
    }

    calcArea() {
        return this.height * this.width;
    }
}

提取字段的操作如下:

  1. 在編輯器中,選擇要轉換為字段的表達式,然后按Ctrl+Alt+F,或從上下文菜單或主菜單上選擇:Refactor|提取|字段?!疤崛∽侄巍睂υ捒驅⒋蜷_。
  2. 從列表中接受一個建議的名稱或鍵入自定義名稱。
  3. 選擇新字段的初始化位置:
    • 目前的方法,見上面的例1。
    • 字段聲明,請參見上面的示例2。
    • 類構造函數(shù),請參見上面的示例3。
    ws_js_extract_field_dialog_1.png

Extract Method

該Extract Method重構,您可以使用提取的代碼創(chuàng)建命名方法或函數(shù)。當調(diào)用Extract Method重構時,IntelliJ IDEA會檢測作為所選代碼片段輸入的變量以及作為其輸出的變量。檢測到的輸出變量用作提取的方法或函數(shù)的返回值。

在下面的示例中,從c = a + b;表達式中提取函數(shù)。

實例1:從另一個函數(shù)內(nèi)的表達式提取一個全局范圍函數(shù)

調(diào)用重構的c = a + b;表達式,位于MyFunction()函數(shù)內(nèi)部。選擇全球目標范圍。

例1.1:生成函數(shù)聲明


function MyFunction(a,b) {
    c = a + b;
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);


function extracted(a, b) {
    c = a + b;
}

function MyFunction(a,b) {
    extracted(a, b);
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);

例1.2:提取的函數(shù)在表達式中聲明


function MyFunction(a,b) {
    c = a + b;
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);


let extracted = function (a, b) {
    c = a + b;
};

function MyFunction(a,b) {
    extracted(a, b);
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);

實例2:從任何函數(shù)之外的表達式提取一個全局范圍函數(shù)

調(diào)用重構的c = a + b;表達式,位于任何函數(shù)之外。因此,無法選擇目標范圍。

例2.1:生成函數(shù)聲明


c = a + b;


function extracted() {
    c = a + b;
}

extracted();

例2.2:提取的函數(shù)在表達式中聲明


c = a + b;


let extracted = function () {
    c = a + b;
};
extracted();

示例3:在封閉函數(shù)內(nèi)提取具有定義的函數(shù)

調(diào)用重構的c = a + b;表達式,位于MyFunction()函數(shù)內(nèi)部。選擇函數(shù)MyFunction目標范圍。


function MyFunction(a,b) {
    c = a + b;
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);


function MyFunction(a,b) {
    function extracted() {
        c = a + b;
    }

    extracted();
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);

提取函數(shù)的操作如下:

  1. 在編輯器中,選擇要轉換為函數(shù)的代碼片段,然后按Ctrl+Alt+M,或從上下文菜單或主菜單上選擇:Refactor|提取|方法。
  2. 如果所選表達式位于函數(shù)內(nèi),請從彈出列表中選擇目標范圍:
    • 如果選擇全局,則提取的函數(shù)將在任何函數(shù)外聲明。參見上面的示例1。
    • 要在當前封閉函數(shù)內(nèi)定義提取的函數(shù),請選擇function <current enclosing function name>。參見上面的實施例3。
      a685a45a-2bf8-46cb-85ee-63e7b26ff646
  3. 要打開包含更多選項的“提取函數(shù)”對話框,請再按一次Ctrl+Alt+M。在此對話框中,您可以選擇是通過生成的函數(shù)聲明還是在表達式內(nèi)聲明提取的函數(shù) 。見上面的例子。
    30f852de-4c11-4acf-a47b-6dae6a0e0017

如何在默認情況下打開“Extract Function”對話框:

  • 在“設置/首選項”對話框(Ctrl+Alt+S)中,單擊:編輯器|常規(guī)。在打開的“常規(guī)”頁面上,清除“重構”區(qū)域中的“啟用in-place模式”復選框。

Extract Superclass

該Extract Superclass(提取超類)重構創(chuàng)建基于當前類的成員一個新的抽象類。創(chuàng)建的類會自動擴展。

假設您有一個類AccountingDepartment,并且您希望來自它的printName()方法能夠重新使用。

class AccountingDepartment {
    name;

    printName() {
        console.log("Department name: " + this.name);
    }

    printMeeting() {
        console.log("The Accounting Department meets each Monday at 10am.");
    }

    generateReports() {
        console.log("Generating accounting reports...");
    }
}

您可以提取超類Department并在其中包含printName該Name字段。

class Department {
    name;

    printName() {
        console.log("Department name: " + this.name);
    }
}

class AccountingDepartment extends Department {
    printMeeting() {
        console.log("The Accounting Department meets each Monday at 10am.");
    }

    generateReports() {
        console.log("Generating accounting reports...");
    }
}

提取超類的操作如下:

  1. 將光標放在要從中提取超類的類的任何位置。
  2. 在主菜單或上下文菜單上選擇:Refactor|提取|超類。“提取超類”對話框將打開。
  3. 指定新超類的名稱,然后選擇要包含在其中的類成員旁邊的復選框。(可選)標記要進行抽象的成員。
  4. 在“目標文件”字段中,指定新類所在文件的位置。默認情況下,該字段顯示調(diào)用重構的當前文件的路徑。
  5. 選擇Extract Superclass。IntelliJ IDEA創(chuàng)建一個新類并使用extends標記源類。
    要創(chuàng)建超類并使用對方法參數(shù)中超類的引用替換對源類的引用,請選擇Extract superclass并盡可能使用它。IntelliJ IDEA在“查找”工具窗口的“重構預覽”窗格中顯示建議的更改。

Extract Vue Component

Extract Vue Component(提取Vue組件)重構允許您從現(xiàn)有組件中提取新的Vue.js組件,而無需任何復制和粘貼。請注意,此重構僅適用于in-place模式,因此請確保在“編輯器:常規(guī)”頁面上選中“啟用in-place模式”復選框 。

提取Vue組件的操作方法如下:

  1. 選擇要提取的模板片段,然后在主菜單或選擇的上下文菜單中選擇:Refactor|提取|提取Vue組件。
  2. 輸入新組件的名稱。如果此名稱已被使用或無效,則IntelliJ IDEA會顯示警告。否則,將創(chuàng)建一個新的單文件組件并將其導入父組件。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號