Go:
Refaktorisering

Hur gör man:

I Go kan refaktorisering sträcka sig från enkla kodändringar till mer komplexa förändringar. Låt oss börja med ett grundläggande exempel: att förenkla en inledande Go-funktion för bättre läsbarhet och effektivitet.

Innan refaktorisering:

package main

import "fmt"

func CalculatePrice(quantity int, price float64) float64 {
    var total float64
    if quantity > 0 {
        total = float64(quantity) * price
    } else {
        total = 0
    }
    return total
}

func main() {
    fmt.Println(CalculatePrice(10, 5.99))  // Utdata: 59.9
}

Efter refaktorisering:

package main

import "fmt"

func CalculatePrice(quantity int, price float64) float64 {
    if quantity > 0 {
        return float64(quantity) * price
    }
    return 0
}

func main() {
    fmt.Println(CalculatePrice(10, 5.99))  // Utdata: 59.9
}

I den refaktoriserade versionen är else borttagen, vilket förenklar funktionens flöde utan att påverka dess utdata - ett exempel på en grundläggande men kraftfull refaktoriseringsmetod i Go.

För ett mer avancerat exempel, överväg att refaktorisera funktioner för att använda gränssnitt för bättre återanvändbarhet och testbarhet:

Innan refaktorisering:

package main

import "fmt"

type Logger struct{}

func (l Logger) Log(message string) {
    fmt.Println("Log:", message)
}

func ProcessData(data string, logger Logger) {
    // Föreställ dig viss databehandling här
    logger.Log("Data processed")
}

func main() {
    logger := Logger{}
    ProcessData("example data", logger)
}

Efter refaktorisering:

package main

import "fmt"

type Logger interface {
    Log(message string)
}

type ConsoleLogger struct{}

func (c ConsoleLogger) Log(message string) {
    fmt.Println("Log:", message)
}

func ProcessData(data string, logger Logger) {
    // Databearbetningen förblir oförändrad
    logger.Log("Data processed")
}

func main() {
    logger := ConsoleLogger{}
    ProcessData("example data", logger)
}

Refaktorisering för att använda ett gränssnitt (Logger) istället för en konkret typ (ConsoleLogger) förbättrar funktionens flexibilitet och kopplar loss databehandlingen från den specifika loggningsimplementeringen.

Fördjupning

Refaktorisering i Go måste balansera enkelhet (en av Gos kärnfilosofier) med den flexibilitet som behövs i stora mjukvaruprojekt. Med tanke på Gos minimalistiska tillvägagångssätt till funktioner - utan generiska typer (fram till nyligen) och med stark betoning på läsbarhet - leder språket naturligtvis utvecklare mot enklare, mer underhållbara kodstrukturer. Detta betyder dock inte att Go-kod inte drar nytta av refaktorisering; det innebär att refaktorisering alltid måste prioritera tydlighet och enkelhet.

Historiskt sett ledde bristen på vissa funktioner i Go (t.ex., generiska typer före Go 1.18) till kreativa men ibland komplicerade lösningar för kodåteranvändning och flexibilitet, vilket gjorde refaktorisering för abstraktion till en vanlig praxis. Med införandet av generiska typer i Go 1.18 refaktoriserar Go-utvecklare nu äldre kod för att utnyttja denna funktion för bättre typsäkerhet och kodåteranvändning, vilket visar den utvecklande karaktären av refaktoriseringspraxis i Go.

Trots detta stöder Gos verktygslåda, inklusive gofmt för kodformatering och go vet för att identifiera misstänkta konstruktioner, att upprätthålla rena kodbasar och minskar behovet av omfattande refaktorisering. Även om refaktorisering är ett ovärderligt verktyg i en Go-programmerares arsenal, kan klokt användande av Gos språkfunktioner och verktyg från början hjälper till att minimera behovet av komplex refaktorisering senare.