[JAVA] Refactoring von Codegerüchen [Feature Neid]

Das dritte Refactoring ist Feature-Neid.

Was ist Feature Neid

Eine Funktion in einem Modul interagiert mit einer Funktion oder Datenstruktur in einem externen Modul und nicht mit einem internen Modul.

Ein häufiges Beispiel ist beispielsweise, wenn Sie die get-Methoden anderer Module in einer Kette verwenden.

Schlechtes Codebeispiel

Siehe zum Beispiel den folgenden Code.

Folgen Sie in der "Hausklasse" der "Personenklasse Adressklasse" und rufen Sie die "calcurateDistance-Methode" der "Adressklasse" auf.

Offensichtlich weiß die Hausklasse zu viel über andere Klassen und verweist zu viel auf sie.

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

Warum schlecht

Warum ist ein so übermäßiger Verweis auf ein externes Modul überhaupt schlecht?

Wenn Sie in erster Linie ein gutes Design erstellen, ist es gut, gut mit dem internen Modul zu interagieren und die Interaktion mit dem externen Modul zu minimieren.

Auf diese Weise

Durch die Kombination der Behandlungen erhöht sich der Aggregationsgrad, und selbst wenn er geändert wird, wird der Effekt verringert.

Lösung

Es gibt zwei mögliche Hauptlösungen:

Schauen wir uns ein Codebeispiel an.

In diesem Codebeispiel gibt es vier Modelle. House Price Address SalesPerson

Angenommen, Sie haben ein Programm, das den Preis eines Hauses oder die Entfernung zu einem Haus berechnet.

Vor dem Refactoring

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

In der SalesPerson-Klasse scheint es zu riechen.

Bei näherer Betrachtung beziehen sich sowohl die Methode berechnePreis als auch die Methode berechne Abstand auf die Feldwerte in der Hausklasse.

Es ist ein typischer Neidgeruch. Das heißt, bezieht sich häufiger auf die Feldwerte des externen Moduls als auf Ihre eigenen Feldwerte. </ b>

Wir werden dies umgestalten.

Welches eignet sich in diesem Fall besser zum Refactoring, zum Verschieben von Feldwerten oder zum Verschieben von Funktionen?

Feldwerte verschieben,

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

Der Geruch in den beiden Funktionen mag verschwunden sein, aber die Kohäsivität des Modells ist gebrochen.

Die SlaesPerson-Klasse erhält irrelevante Daten wie den Adresspreis.

Bewegen wir die Funktion gehorsam.

Nach dem 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
                        )

Durch das Verschieben der beiden Funktionen in die House-Klasse verschwand der Merkmal-Neid-Geruch, und das Verhalten der House-Klasse nahm zu und der Aggregationsgrad nahm zu.

Zusammenfassung

Wie mein Gefühl Wenn Sie versuchen, auf die Daten im nächsten oder sogar im nächsten Modul zuzugreifen, sollten Sie vermuten, dass es sich um einen Feature-Neid handelt.

Ist der Ort, an dem die Funktion definiert ist, anders als im obigen Refactoring, oder ist es besser, die Feldwerte des Objekts zu verschieben?

Danke bis zum Ende.

Nächstes Mal werde ich einen Artikel über faulen Unterricht schreiben.

Referenz

Recommended Posts

Refactoring von Codegerüchen [Feature Neid]
Code Geruch Refactoring [faule Klasse]
Code Geruch Refactoring 1. [lange Methode]