[JAVA] odeur de code Refactoring 1er [méthode longue]

J'ai refactorisé avec mes seniors dans une entreprise qui a rejoint un nouveau diplômé en avril de cette année, j'écrirai donc un article sous la forme d'une série de ce que j'ai appris sur la refactorisation là-bas.

Cette fois, j'expliquerai le refactoring de la méthode longue.

S'il y a quelque chose qui ne va pas, je serai heureux de pleurer si vous le signalez mm

Langue à utiliser

--scala (parfois java)

Quelle est la méthode longue

Comme son nom l'indique, la méthode contient trop de code.

Pourquoi coder l'odeur?

Pourquoi est-ce le problème qu'il y a trop de code dans la méthode en premier lieu?

Il y a deux points possibles.

1. C'est tout simplement difficile à lire, il est donc difficile de suivre le processus

Par exemple, si vous écrivez environ 100 lignes de code pour la même méthode, vous abandonnerez la lecture vers la troisième ligne.

2. C'est un foyer de bogues car il est difficile d'effectuer des tests unitaires (UT).

Si vous effectuez plusieurs processus dans la même fonction, il est difficile de UT, donc cela devient un foyer de bogues au moment où il n'est pas couvert.

Dans l'exemple suivant, la méthode createUrl comprend deux processus, l'un consiste à obtenir la valeur de redis et l'autre à créer une URL.


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

Cause de devenir une longue méthode

Alors pourquoi la fonction est-elle si longue?

Il y a deux causes principales possibles:

1. Exécution de plusieurs processus dans une fonction (ayant plusieurs concepts)

2. Le degré d'abstraction du traitement dans la fonction n'est pas uniforme

Solution

Si vous éliminez une par une les deux causes répertoriées ci-dessus, l'odeur de code de la méthode longue est susceptible de disparaître.   Il existe de nombreuses façons de résoudre la méthode longue, donc la méthode à appliquer dépend de la méthode longue que vous utilisez. Alors, c'est tout! !! !! Je ne peux pas dire ça

En général, je pense que cela peut être résolu en faisant le suivant comme un grand concept de la méthode de résolution de la méthode longue.

Fonction d'extraction

Il existe différentes manières de penser l'extraction de cette fonction.

Extrayez simplement vers une méthode privée dans la même classe.

Le traitement dans la méthode est compliqué, et le traitement spécifique n'est écrit que si, le degré d'abstraction n'est donc pas uniforme, il est donc difficile à lire.

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

Le fait d'apporter le contenu de if à une méthode privée facilite la lecture car le degré d'abstraction de la méthode est aligné.

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

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

Apportez la méthode à une autre classe.

Refactoriser davantage l'exemple précédent en termes d'agglomération.

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
}

Les résultats de recherche sont plus agrégés, ce qui les rend encore plus faciles à lire.

Le degré de cohésion sera discuté dans le prochain article de refactoring de grande classe.

Si vous effectuez plusieurs processus, divisez chaque processus en méthodes.

Dans le premier exemple, plusieurs processus sont exécutés dans une méthode.

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

Le processus de création d'une URL et le processus d'obtention d'un mot-clé de redis sont complètement séparés. Dans la méthode createUrl, au lieu d'appeler getKeyWord L'appelant de chaque méthode (méthode principale dans ce cas) appelle chaque méthode.

Ce faisant, le degré d'abstraction du processus sera uniforme et il sera beaucoup plus facile à lire.

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}"
}

Résumé

Cette fois, j'ai présenté un exemple de refactoring lié à la méthode longue.

Si vous êtes conscient des deux points suivants, vous pourrez forcément définir des méthodes sans odeurs.

--Une méthode effectue un processus

Merci jusqu'à la fin.

La prochaine fois, j'écrirai une explication de refactoring sur la grande classe.

Puis.

référence

Recommended Posts

odeur de code Refactoring 1er [méthode longue]
refactoring d'odeur de code [classe paresseuse]
refactoring de l'odeur du code [fonctionnalité envie]
Comment remplir le code avec Qiita
Collection de méthodes de code de test Java