[JAVA] refactoring de l'odeur du code [fonctionnalité envie]

Le troisième refactoring est l'envie des fonctionnalités.

Qu'est-ce que l'envie de fonctionnalité

Une fonction dans un module interagit avec une fonction ou une structure de données dans un module externe plutôt qu'avec un module interne.

Par exemple, un exemple courant est lorsque vous utilisez les méthodes get d'autres modules d'une chaîne.

Exemple de code incorrect

Par exemple, consultez le code ci-dessous.

A partir de la classe Maison, nous suivons la classe Person Adress class et appelons la méthode calcurateDistance de la ʻAdress class`.

De toute évidence, la classe House en sait trop sur les autres classes et y fait trop référence.

House().getPerson().getAdress().calcurateDistance()

Pourquoi mauvais

Alors pourquoi une référence aussi excessive à un module externe est-elle mauvaise en premier lieu?

En premier lieu, lors d'une bonne conception, il est bon de bien interagir avec le module interne et de minimiser l'interaction avec le module externe.

En faisant cela,

En combinant les processus, le degré d'agrégation augmente, et même s'il est modifié, l'effet est réduit.

Solution

Il existe deux principales solutions possibles:

Regardons en fait un exemple de code.

Dans cet exemple de code, il existe quatre modèles. House Price Address SalesPerson

Supposons que vous ayez un programme qui calcule le prix d'une maison ou la distance d'une maison.

Avant de refactoriser

class Main {
  def main(args: Array[String]): Unit = {
    val address = Address(1L, 1L, 100L)
    val price = Price(10000)
    val house = House(address, price)
    val salesPerson = SalesPerson(1, "kin", house)

    salesPerson.calculatePrice

  }

  case class House(address: Address, price: Price)

  case class Price(number: Int)

  case class Address(
                      longitude: Long,
                      latitude: Long,
                      price: Long
                    )


  case class SalesPerson(
                          id: Int,
                          name: String,
                          house: House
                        ) {
    def calculatePrice: Int = {
      (house.price.number * 1.1).toInt
    }

    def calculateDistance: Long = {
      house.address.longitude
    }
  }
 
}

Il semble y avoir une odeur dans la classe SalesPerson.

Si vous regardez de plus près, les méthodes CalculatePrice et CalculateDistance font toutes deux référence aux valeurs de champ de la classe maison.

C'est une odeur d'envie caractéristique. Autrement dit, fait plus souvent référence aux valeurs de champ du module externe qu'à vos propres valeurs de champ. </ b>

Nous allons refactoriser cela.

Qu'est-ce qui convient le mieux pour refactoriser dans ce cas, déplacer des valeurs de champ ou déplacer des fonctions?

Déplacer les valeurs de champ,

case class House() {
  }

  case class SalesPerson(id: Int, name: String, house: House, address: Address, price: Price) {
    def calculatePrice: Int = {
      (price.number * 1.1).toInt
    }

    def calculateDistance: Long = {
      address.longitude
    }
  }

L'odeur des deux fonctions a peut-être disparu, mais la cohésion du modèle est rompue.

La classe SlaesPerson se retrouvera avec des données non pertinentes telles que le prix de l'adresse.

Déplaçons la fonction docilement.

Après refactoring



def main(args: Array[String]): Unit = {
    val address = Address(1L, 1L, 100L)
    val price = Price(10000)
    val house = House(address, price)
    val salesPerson = SalesPerson(1, "kin", house)

//    salesPerson.calculatePrice
    house.calculatePrice

    house.calculateDistance
    
  }

  case class House(address: Address, price: Price) {
    def calculatePrice: Int = {
      (price.number * 1.1).toInt
    }

    def calculateDistance: Long = {
      address.longitude
    }
  }

  case class SalesPerson(
                          id: Int,
                          name: String,
                          house: House
                        )

En déplaçant les deux fonctions vers la classe Maison, l'odeur d'envie des fonctionnalités a disparu, et le comportement de la classe Maison a augmenté et le degré d'agrégation a augmenté.

Résumé

Comme mon sentiment Si vous essayez d'accéder aux données du module suivant, vous devriez penser que c'est une fonctionnalité envieuse.

L'emplacement où la fonction est définie est-il différent, comme dans la refactorisation ci-dessus, ou vaut-il mieux déplacer les valeurs de champ de l'objet?

Merci jusqu'à la fin.

La prochaine fois, j'écrirai un article sur la classe paresseuse.

référence

Recommended Posts

refactoring de l'odeur du code [fonctionnalité envie]
refactoring d'odeur de code [classe paresseuse]
odeur de code Refactoring 1er [méthode longue]