[JAVA] Code Geruch Refactoring 1. [lange Methode]

Ich habe mit meinen Senioren in einem Unternehmen, das im April dieses Jahres einem neuen Absolventen beigetreten ist, ein Refactoring durchgeführt. Daher werde ich einen Artikel in Form einer Reihe von Informationen schreiben, die ich über das Refactoring dort gelernt habe.

Dieses Mal werde ich das Refactoring der langen Methode erklären.

Wenn etwas nicht stimmt, werde ich gerne weinen, wenn Sie darauf hinweisen, mm

Zu verwendende Sprache

--scala (manchmal Java)

Was ist die lange Methode

Wie der Name schon sagt, enthält die Methode zu viel Code.

Warum Code riechen?

Warum ist es das Problem, dass die Methode überhaupt zu viel Code enthält?

Es gibt zwei mögliche Punkte.

1. Es ist einfach schwer zu lesen, daher ist es schwierig, den Prozess zu verfolgen

Wenn Sie beispielsweise ungefähr 100 Codezeilen für dieselbe Methode schreiben, geben Sie das Lesen in ungefähr der dritten Zeile auf.

2. Es ist eine Brutstätte von Fehlern, da es schwierig ist, einen Unit-Test (UT) durchzuführen.

Wenn Sie mehrere Prozesse in derselben Funktion ausführen, ist UT schwierig zu erstellen, sodass es in dem Moment, in dem es nicht behandelt wird, zu einer Brutstätte von Fehlern wird.

Im folgenden Beispiel enthält die Methode createUrl zwei Prozesse, von denen einer den Wert von redis abruft und der andere die URL erstellt.


def createUrl(key: String): String = {
  val keyword = redisClient.getCaches(key).orElse("hoge")
  s"http://localhost:9000?q=${keyword}"
}

Ursache, eine lange Methode zu werden

Warum ist die Funktion so lang?

Es gibt zwei mögliche Hauptursachen:

1. Mehrere Prozesse in einer Funktion ausführen (mit mehreren Konzepten)

2. Der Abstraktionsgrad der Verarbeitung in der Funktion ist nicht einheitlich

Lösung

Wenn Sie die beiden oben aufgeführten Ursachen nacheinander beseitigen, verschwindet der Codegeruch der langen Methode wahrscheinlich.   Es gibt viele Möglichkeiten, die lange Methode zu lösen. Welche Methode angewendet werden soll, hängt also von der langen Methode ab, die Sie anwenden. Das ist also alles! !! !! Das kann ich nicht sagen

Im Allgemeinen denke ich, dass es gelöst werden kann, indem das folgende als großes Konzept der Lösungsmethode der langen Methode verwendet wird.

Funktion extrahieren

Es gibt verschiedene Denkweisen, um diese Funktion zu extrahieren.

Extrahieren Sie einfach in eine private Methode innerhalb derselben Klasse.

Die Verarbeitung in der Methode ist kompliziert, und die konkrete Verarbeitung wird nur dann geschrieben, wenn der Abstraktionsgrad nicht einheitlich ist und daher schwer zu lesen ist.

def search(searchResult: SearchResult): String = {
  if(searchResult.totalHits > 0 || searchResult.result.nonEmpty) {
   Ok(
     createResponse(.....)
    )
  } else {
    NotFound
  }
}

Wenn Sie den Inhalt von if auf eine private Methode übertragen, wird das Lesen einfacher, da der Abstraktionsgrad in der Methode ausgerichtet ist.

def search(searchResult: SearchResult): String = {
  if(existSearchResult(searchResult)) {
   Ok(
     createResponse(.....)
    )
  } else {
    NotFound
  }
}

private def existSearchResult(searchResult: SearchResult): Boolean = {
  searchResult.totalHits > 0 || searchResult.result.nonEmpty
}

Bringen Sie die Methode in eine andere Klasse.

Um das vorherige Beispiel in Bezug auf die Agglomeration weiter zu überarbeiten.

def search(searchResult: SearchResult): String = {
  if(searchResult.hasContent) {
   Ok(
     createResponse(.....)
    )
  } else {
    NotFound
  }
}

case class SearchResult(
  totalHits: Long,
  result: Option[Result]
) {
  def hasContent: Boolean = totalHits > 0 || result.isDefined
}

SearchResults sind aggregierter, wodurch sie noch einfacher zu lesen sind.

Der Grad der Kohäsion wird im nächsten Artikel zum Refactoring großer Klassen erörtert.

Wenn Sie mehrere Prozesse ausführen, teilen Sie jeden Prozess in Methoden auf.

Im ersten Beispiel werden mehrere Prozesse in einer Methode ausgeführt.

def createUrl(key: String): String = {
  val keyword = redisClient.getCaches(key).orElse("hoge")
  s"http://localhost:9000?q=${keyword}"
}

Der Prozess zum Erstellen einer URL und der Prozess zum Abrufen eines Schlüsselworts von redis sind vollständig voneinander getrennt. In der createUrl-Methode, anstatt getKeyWord aufzurufen Der Aufrufer jeder Methode (in diesem Fall die Hauptmethode) ruft jede Methode auf.

Auf diese Weise wird der Abstraktionsgrad des Prozesses einheitlich und es ist viel einfacher zu lesen.

def main() {
  val keyword = getKeyWord(key)
  createUrl(keyword)
}

private getKeyWord(key: String): String = {
  redisClient.getCaches(key).orElse("hoge")
}

private def createUrl(key: String): String = {
  s"http://localhost:9000?q=${keyword}"
}

Zusammenfassung

Dieses Mal habe ich ein Beispiel für Refactoring im Zusammenhang mit der langen Methode vorgestellt.

Wenn Sie die folgenden zwei Punkte kennen, können Sie unweigerlich Methoden ohne Gerüche definieren.

Danke bis zum Ende.

Nächstes Mal werde ich eine Refactoring-Erklärung über die große Klasse schreiben.

Dann.

Referenz

Recommended Posts

Code Geruch Refactoring 1. [lange Methode]
Code Geruch Refactoring [faule Klasse]
Refactoring von Codegerüchen [Feature Neid]
So füllen Sie den Code mit Qiita aus
Sammlung von Java-Testcode-Methoden