Das dritte Refactoring 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.
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 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
Es gibt zwei mögliche Hauptlösungen:
Funktion verschieben
Feldwert verschieben
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.
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.
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.
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.