เนื้อหา

ทริกง่าย ๆ กับการเขียนโค้ดไม่ให้บรรพบุรุษเดือดร้อน

ในการเขียนโค้ดกันเป็นทีมมันจะมีเรื่องชวนปวดหัวบ่อย ๆ เลยคือ ใครเขียนโค้ดนี้ว่ะ 🤬 เลยจะต้องมีสิ่งพึงละลึกร่วมกัน หรือตกลงกันในทีมในการเขียนโค้ดให้การกระทบกระทั้งกันน้อยลง โดยจะเอาวิธีง่าย ๆ ที่ช่วยให้ชีวิตชาวเราดีขึ้นมาเสนอลองพิจารณาดูครับ

โค้ดเจ้าปัญหา

เริ่มจากโค้ดเจ้าปัญหาที่เกิดจากการทำงานแบบปะผุ It works

func main() {
    ...
    if isLogedIn {
        if isStaff {
            if isInFinanceDepartment {
                for _, v := range products {
                    switch v.Cat {
                        case "food":
                            rwMutex.Lock()
                            receipt["price"] += v.Amount + v.AddedAmount
                            rwMutex.Unlock()
                        case "drink":
                            rwMutex.Lock()
                            receipt["price"] += v.Amount + v.AddedAmount
                            rwMutex.Unlock()
                        case "alcohol":
                            rwMutex.Lock()
                            receipt["price"] += v.Amount + receipt["tax"]
                            rwMutex.Unlock()
                        default:
                            rwMutex.Lock()
                            receipt["price"] += v.Amount
                            rwMutex.Unlock()
                    }
                }
            } else {
                slog.Warn("main", "isInFinanceDepartment", false)
                return ...
            }
        } else {
            slog.Warn("main", "isStaff", false)
            return ...
        }
    } else {
        slog.Warn("main", "isLogedIn", false)
        return ... 
    }

    p(products, total)
    ...
}

หลีกเลี่ยงการเขียนโค้ดซ้อนกันหลายชั้นใน 1 บล็อค

ก็คือลดความซับซ้อนของโค้ดเวลาอ่าน จะได้ไม่ต้องจำว่ามันอยู่ในวงไหนกันนะ

ยุบ nested if ด้วย inversion

จากของเดิมจะเห็นหว่ามี if ครอบอยู่หลายชั้นมาก ซึ่งส่วนมากแล้วถ้าเราไม่ได้ทำงานแยกกันระหว่าง if else เราสามารถยุบ if ได้ตามนี้

func main() {
    ...
    if !isLogedIn {
        slog.Warn("main", "isLogedIn", false)
        return ... 
    }

    if !isStaff || !isInFinanceDepartment {
        slog.Warn("main", "isStaffInFinanceDepartment", false)
        return ...
    }

    for _, v := range products {
        switch v.Cat {
            case "food":
                rwMutex.Lock()
                receipt["price"] += v.Amount + v.AddedAmount
                rwMutex.Unlock()
            case "drink":
                rwMutex.Lock()
                receipt["price"] += v.Amount + v.AddedAmount
                rwMutex.Unlock()
            case "alcohol":
                rwMutex.Lock()
                receipt["price"] += v.Amount + receipt["tax"]
                rwMutex.Unlock()
            default:
                rwMutex.Lock()
                receipt["price"] += v.Amount
                rwMutex.Unlock()
        }
    }

    p(products, receipt)
    ...
}

ย้ายสิ่งที่เป็น logic ซับซ้อนออกมาเป็นฟังก์ชัน

เอา logic ที่อ่านยาก ๆ ยาว ๆ ออกมาเป็นชื่อที่ระบุว่า logic นั้นทำอะไร

func isFinanceStaff() bool {
    return isStaff && isInFinanceDepartment
}

func main() {
    ...
    if !isLogedIn {
        slog.Warn("main", "isLogedIn", false)
        return ... 
    }

    if isFinanceStaff() {
        slog.Warn("main", "isFinanceStaff", false)
        return ...
    }

    for _, v := range products {
        switch v.Cat {
            case "food":
                rwMutex.Lock()
                receipt["price"] += v.Amount + v.AddedAmount
                rwMutex.Unlock()
            case "drink":
                rwMutex.Lock()
                receipt["price"] += v.Amount + v.AddedAmount
                rwMutex.Unlock()
            case "alcohol":
                rwMutex.Lock()
                receipt["price"] += v.Amount + receipt["tax"]
                rwMutex.Unlock()
            default:
                rwMutex.Lock()
                receipt["price"] += v.Amount
                rwMutex.Unlock()
        }
    }

    p(products, receipt)
    ...
}

ทำให้โค้ดใช้ซ้ำได้ ลดความทับซ้อนของโค้ด

โค้ดไหนที่มีการสร้างมาซ้ำ ๆ แต่ไม่ได้ทำงานต่างกันก็ยุบรวมไปให้ใช้งานซ้ำ ๆ กันได้จากที่เดียวกัน

func isFinanceStaff() bool {
    return isStaff && isInFinanceDepartment
}

func main() {
    ...
    if !isLogedIn {
        slog.Warn("main", "isLogedIn", false)
        return ... 
    }

    if isFinanceStaff() {
        slog.Warn("main", "isFinanceStaff", false)
        return ...
    }

    rwMutex.Lock()
    receipt["price"] := SumProductPrice(products, receipt["tax"])
    rwMutex.Unlock()

    p(products, totalPrice)
    ...
}

func SumProductPrice(products []Product, tax float64) total float64 {
    for _, v := range products {
        switch v.Cat {
            case "food":
                total += v.Amount + v.AddedAmount
            case "drink":
                total += v.Amount + v.AddedAmount
            case "alcohol":
                total += v.Amount + tax
            default:
                total += v.Amount
        }
    }
}

อย่าตั้งชื่อให้เข้าใจอยู่คนเดียว

การระบุชื่อในโค้ด ให้ใช้คำที่ลูกค้าเข้าใจ เพื่อนร่วมทีมเข้าใจ แล้วเราก็จะเข้าใจกัน

func isFinanceStaff() bool {
    return isStaff && isInFinanceDepartment
}

func main() {
    ...
    if !isLogedIn {
        slog.Warn("main", "isLogedIn", false)
        return ... 
    }

    if isFinanceStaff() {
        slog.Warn("main", "isFinanceStaff", false)
        return ...
    }

    receiptMutex.Lock()
    receipt["totalPrice"] := SumProductPrice(orderProducts, receipt["tax"])
    receiptMutex.Unlock()

    PrintReceipt(orderProducts, totalPrice)
    ...
}

func SumProductPrice(orderProducts []Product, tax float64) total float64 {
    for _, orderItem := range orderProducts {
        switch orderItem.Category {
            case "food":
                total += orderItem.Price + orderItem.GasPrice
            case "drink":
                total += orderItem.Price + orderItem.PackagePrice
            case "alcohol":
                total += orderItem.Price + tax
            default:
                total += orderItem.Price
        }
    }
}

สรุป

ก็ลองไปปรับใช้กันดูนะครับเผื่อจะมีคนพาดพิงน้อยลงเวลาที่มีคนเอาโค้ดเราไปทำงานต่อ Happy coding กันครับ