在IntelliJ下如何做parameterize method的重構

今天在做項目的時候,發現在測試代碼中有一個bad smell。準備測試數據的代碼在結構上是類似的,可以用parameterize method的方法進行重構。

爲了說明,我就構造了一些簡單的示例,示例很簡單,只是爲了演示重構步驟。


下面的代碼都是new了一個person再setName(紅色部分代碼)。這個步驟是相似的,完全可以抽方法來準備具有名字的person。

    @Test
    public void should_new_person_with_good_name() {
        Person person = new Person();
        person.setName("kiwi");

        assertThat(person.getName(), is(equalTo("kiwi")));
    }

    @Test
    public void should_new_person_with_bad_name() {
        Person person = new Person();
        person.setName("sb");

        assertThat(person.getName(), is(equalTo("sb")));
    }


方法一:抽方法+提取方法參數(不推薦)

1.先抽方法(command + alt + M):

    private Person getPerson() {
        Person person = new Person();
        person.setName("kiwi");
        return person;
    }

2.提參數(command + alt + P):

    private Person getPerson(String name) {
        Person person = new Person();
        person.setName(name);
        return person;
    }

然後這樣做了以後,代碼就變成這B樣了,intellij並沒有發現這個具有相似結構的代碼(紅色部分並沒有改變):

    @Test
    public void should_new_person_with_good_name() {
        Person person = getPerson("kiwi");
        assertThat(person.getName(), is(equalTo("kiwi")));
    }

    private Person getPerson(String name) {
        Person person = new Person();
        person.setName(name);
        return person;
    }

    @Test
    public void should_new_person_with_bad_name() {
        Person person = new Person();
        person.setName("sb");

        assertThat(person.getName(), is(equalTo("sb")));
    }

你需要去手動的找每一個可以用getPerson(String name)的地方,然後再替換,可以想象的是,如果可以替換的地方很多,你就悲催了。

我們希望儘可能的讓ide完成這些工作。所以,我推薦使用第二種方法。


方法二:提取局部變量+抽方法

1.提取局部變量(command + alt + V)

    @Test
    public void should_new_person_with_good_name() {
        String name = "kiwi";
        Person person = new Person();
        person.setName(name);

        assertThat(person.getName(), is(equalTo("kiwi")));
    }

首先提取變量,將變量移到欲提取的方法體的外部。

2.提取方法(command + alt + M)

這個時候intellij會提示你有重複的代碼,選擇全部替換,就OK了

    @Test
    public void should_new_person_with_good_name() {
        String name = "kiwi";
        Person person = getPerson(name);
        assertThat(person.getName(), is(equalTo("kiwi")));
    }


    private Person getPerson(String name) {
        Person person = new Person();
        person.setName(name);
        return person;
    }


    @Test
    public void should_new_person_with_bad_name() {
        Person person = getPerson("sb");
        assertThat(person.getName(), is(equalTo("sb")));
    }

3.Inline局部變量(optional)

這個時候可以把原來的局部變量inline回去了,如果需要的話。


我使用的intellij是12的community版,使用這樣的方法,你就不用再一點點的去找可能重複的地方了。有時候intellij也不是那麼的intelligent。

發佈了154 篇原創文章 · 獲贊 17 · 訪問量 87萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章