• <menu id="w2i4a"></menu>
  • logo IntelliJ IDEA系列教程:

    文檔首頁>>IntelliJ IDEA系列教程:>>IntelliJ IDEA教程:內(nèi)聯(lián)方法重構(gòu)

    IntelliJ IDEA教程:內(nèi)聯(lián)方法重構(gòu)


    點擊下載IntelliJ IDEA最新試用版

    內(nèi)聯(lián)方法重構(gòu)的思想很簡單 - 用其內(nèi)容替換方法調(diào)用。它仍然非常強大。但要了解它的力量,你需要知道它的用例。

    讓我們了解為什么,何時以及如何應用內(nèi)聯(lián)方法重構(gòu)以及IntelliJ IDEA如何幫助您入門。

    一個方法的流程中斷

    當方法調(diào)用中斷方法中的流而不是簡化它時,您可以考慮應用內(nèi)聯(lián)方法。在下面的代碼中,對方法的調(diào)用是在方法compareRatingWithMethodParameter()中插入不必要的間接方法scheduleSession()。

    public class Talk {
        int rating;
     
        LocalTime scheduleSession() {
            return compareRatingWithMethodParameter(3) ?
                    LocalTime.of(9, 0) :
                    LocalTime.of(10, 0);
        }
     
        private boolean compareRatingWithMethodParameter(int param) {
            return rating < param;
        }
    }

    通過內(nèi)聯(lián)方法可以簡化上面的代碼compareRatingWithMethodParameter():

    IntelliJ IDEA教程:內(nèi)聯(lián)方法重構(gòu)

    但是,您不必內(nèi)聯(lián)每個只定義一行代碼的方法。決定應取決于它是否有助于您了解方法中的流程。

    代碼遷移,或使用最新的Java語言功能

    將代碼遷移到以后的Java版本時,您可能希望內(nèi)聯(lián)幾種方法,以便可以將操作應用于多個方法的代碼。
    雖然在方法中的代碼getSortedListOfNames()看起來可讀,通過內(nèi)聯(lián)方法extractNamesFromSpeakerList()和sortSpeakerNames(),你可以重構(gòu)它使用Java流,而不是使用for循環(huán)和Collections.sort單獨的方法。這是原始代碼:

     List getSortedListOfNames(List speakers) {
            List speakerNames = extractNamesFromSpeakerList(speakers);
            sortSpeakerNames(speakerNames);
            return speakerNames;
        }
     
        private void sortSpeakerNames(List speakerNames) {
            Collections.sort(speakerNames);
        }
     
        private List extractNamesFromSpeakerList(List speakers) {
            List result = new ArrayList<>();
            for (Speaker speaker : speakers) {
                result.add(speaker.getName());
            }
            return result;
    }

    以下是如何內(nèi)聯(lián)方法并重構(gòu)生成的代碼:

    IntelliJ IDEA教程:內(nèi)聯(lián)方法重構(gòu)

    這是重構(gòu)的代碼,您可以與原始代碼進行比較:

       List getSortedListOfNames(List speakers) {
        return speakers.stream()
                .map(Speaker::getName)
                .sorted()
                .collect(Collectors.toList());
    }

    一組嚴重重構(gòu)的方法

    程序員通常最終難以應用重構(gòu)實踐。例如,在下面的代碼中,程序員似乎已經(jīng)對每個單獨的代碼行應用了“Extract Method Refactoring”。

    雖然它看起來仍然可讀,但是內(nèi)聯(lián)其中一些方法并將一個或多個方法的代碼組合到另一個方法中,然后進行(合理的)重構(gòu),可以改善代碼的意圖:

    List getPanelists(Track track, List speakerList) {
            outputTrackName(track);
            outputSpeakerList(speakerList);
            List panelists = filterSpeakersWithoutTracks(speakerList);
            panelists = findSpeakerSpeakingOnTrack(track, panelists);
            return panelists;
        }
     
        private void outputTrackName(Track track) {
            System.out.println("Looking for panelists for track : " + track);
        }
     
        private void outputSpeakerList(List list) {
            list.forEach(System.out::println);
        }
     
        private List filterSpeakersWithoutTracks(List list) {
            return list.stream().
                    filter(s -> s.speakingOn != null)
                    .collect(Collectors.toList());
        }
     
        private List findSpeakerSpeakingOnTrack(Track track, List list) {
            return list.stream()
                    .filter(s -> s.isSpeakingOn(track))
                    .collect(Collectors.toList());
        }

    讓我們看看我們?nèi)绾沃匦陆M織代碼。讓我們內(nèi)聯(lián)幾個方法,然后將代碼提取到方法中,使代碼簡潔易讀。

    1565764599.png

    同樣,這是您與初始代碼進行比較的最終代碼:

     List getPanelists(Track track, List speakerList) {
            outputParamValues(track, speakerList);
            return speakerList.stream().
                    filter(s -> s.speakingOn != null && s.isSpeakingOn(track))
                    .collect(Collectors.toList());
        }
     
        private void outputParamValues(Track track, List speakerList) {
            System.out.println("Looking for panelists for track : " + track);
            speakerList.forEach(System.out::println);
        }

    內(nèi)聯(lián)方法改進

    (IntelliJ IDEA 2019.2中的新功能)

    IntelliJ IDEA 2019.2包含對Inline Method重構(gòu)的重大改進。
    通過定義多個return語句,方法可能包含多個出口點。當您在IntelliJ IDEA 2019.2中內(nèi)聯(lián)這樣的方法時,可以修改它以僅以單個return語句的形式定義一個退出點,以退出該方法。IntelliJ IDEA將此稱為“轉(zhuǎn)換為單一退出點”功能。

    在下面的代碼中,當您內(nèi)聯(lián)方法時isBreakRequiredBetweenSession(),該過程會引入變量結(jié)果。多個return語句將替換為變量的賦值,最后result只有一個return語句:

      void outputBreak() {
            boolean breakReq = isBreakRequiredBetweenSession();
            System.out.println("Break required = " + breakReq);
        }
     
        private boolean isBreakRequiredBetweenSession() {
            if (isWeekend())
                if (isDurationGreaterThan50min())
                    return true;
                else
                    return false;
            else
                return false;
    }

    讓我們內(nèi)聯(lián)方法isBreakRequiredBetweenSession():

    IntelliJ IDEA教程:內(nèi)聯(lián)方法重構(gòu)

    如您所見,修改后的代碼更容易遵循 - 因為它沒有多個退出點。這是您與初始代碼進行比較的最終代碼:

      void outputBreak() {
            boolean breakReq;
            if (isWeekend())
                if (durationGreaterThan50min())
                    breakReq = true;
                else
                    breakReq = false;
            else
                breakReq = false;
            System.out.println("Break required = " + breakReq);
    }

    開發(fā)人員通常return在方法中定義多個語句,這些語句從各種控制語句(如if,for和其他語句)返回值。通常這種方法最后還包括一個return陳述。這是一個示例,它acceptSpeaker()使用行尾注釋在方法中定義多個出口點:

     boolean acceptSession(Speaker speaker, Talk talk) {
            List days = List.of(DayOfWeek.SUNDAY, DayOfWeek.SATURDAY);
            if (speaker.getName().equals("JavaGuru"))
                return true;                                // Exit Point 1
            if (talk.getTrack() == Track.SCALA) {
                return false; // Exit Point 2
            }
            for (DayOfWeek day : days) {
                if(talk.date.getDayOfWeek().equals(day)) {
                    return true; // Exit Point 3
                }
            }
            return false;
        }
     
        boolean submitTalk(Speaker speaker, Talk talk) {
            System.out.println("Received another submission");
            boolean isAccepted = acceptSession(speaker, talk);
            if (isAccepted) {
                // Update website
            }
            return isAccepted;
    }

    當您在內(nèi)聯(lián)方法acceptSession()時submitTalk(),IntelliJ IDEA將檢測其多個退出語句并相應地修改代碼:

    IntelliJ IDEA教程:內(nèi)聯(lián)方法重構(gòu)

    以下是您要比較的最終代碼(為方便起見添加了行尾注釋):

      boolean submitTalk(Speaker speaker, Talk talk) {
            System.out.println("Received another submission");
            boolean isAccepted = false;
            List days = List.of(DayOfWeek.SUNDAY, DayOfWeek.SATURDAY);
            if (speaker.getName().equals("JavaGuru")) {
                isAccepted = true;                       // Assignment
            } else {
                if (talk.getTrack() != Track.SCALA) {
                    for (DayOfWeek day : days) {
                        if (talk.date.getDayOfWeek().equals(day)) {
                            isAccepted = true;           // Assignment
                            break;                       // break statement added
                        }
                    }
                }
            }
            if (isAccepted) {
                // Update website
            }
            return isAccepted;                           // single return statement
    }

    具有否定的內(nèi)聯(lián)方法

    (IntelliJ IDEA 2019.2中的新功能)

    通過IntelliJ IDEA 2019.2的增強功能,內(nèi)聯(lián)方法重構(gòu)還支持呼叫站點的否定。在下面的代碼中,當您在方法中check()使用否定方法內(nèi)聯(lián)方法時isValidName(),它將不會被修改為“單個退出點”:

     boolean check(Speaker speaker) {
            if (speaker == null) return false;
            String name = speaker.name.trim();
            if (name.isEmpty()) return false;
            return name.length() % 2 == 0;
        }
     
        boolean isValidName(Speaker speaker) {
            return !check(speaker);
    }

    這是內(nèi)聯(lián)代碼被否定的方式 - 注意返回值的反轉(zhuǎn)和條件(name.length() % 2 == 0)到(name.length() % 2 != 0):

    IntelliJ IDEA教程:內(nèi)聯(lián)方法重構(gòu)

    以下是修改后的代碼,供您與原始代碼進行比較:

     boolean isValidName(Speaker speaker) {
            if (speaker == null) return true;
            String name = speaker.name.trim();
            if (name.isEmpty()) return true;
            return name.length() % 2 != 0;
        }

    快樂的編碼和合理的重構(gòu)!

    IntelliJ IDEA為您自動化各種重構(gòu)選項起著至關(guān)重要的作用。感興趣的朋友趕快下載體驗吧~

    想要購買IntelliJ IDEA正版授權(quán)的朋友可以咨詢慧都官方客服。

    圖片2.jpg


    掃碼咨詢


    添加微信 立即咨詢

    電話咨詢

    客服熱線
    023-68661681

    TOP
    三级成人熟女影院,欧美午夜成人精品视频,亚洲国产成人乱色在线观看,色中色成人论坛 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();