ทริกง่าย ๆ กับการเขียนโค้ดไม่ให้บรรพบุรุษเดือดร้อน
ในการเขียนโค้ดกันเป็นทีมมันจะมีเรื่องชวนปวดหัวบ่อย ๆ เลยคือ ใครเขียนโค้ดนี้ว่ะ 🤬 เลยจะต้องมีสิ่งพึงละลึกร่วมกัน หรือตกลงกันในทีมในการเขียนโค้ดให้การกระทบกระทั้งกันน้อยลง โดยจะเอาวิธีง่าย ๆ ที่ช่วยให้ชีวิตชาวเราดีขึ้นมาเสนอลองพิจารณาดูครับ
โค้ดเจ้าปัญหา
เริ่มจากโค้ดเจ้าปัญหาที่เกิดจากการทำงานแบบปะผุ 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 กันครับ