อะไรคือสิ่งที่นิยาม 'วัน'?
โปรแกรมเมอร์มักจะโฟกัสผิดจุดเมื่อต้องสร้างฟีเจอร์ใหม่ๆ
คุณอาจจะนึกถึงข้อมูลหลังบ้าน (backend data), การเขียนโค้ดซ้ำซ้อน (code duplication) หรือประสิทธิภาพ (performance) คำถามเหล่านี้สำคัญ แต่ไม่ใช่คำถามที่สำคัญที่สุด
ผมเองก็มักจะทำผิดพลาดแบบนี้บ่อยๆ ผมตื่นเต้นกับแพทเทิร์นที่ชาญฉลาดและโค้ดที่สะอาด (clean code) ผมเริ่มเขียนโค้ดก่อนที่จะเข้าใจอย่างถ่องแท้ว่าผู้ใช้งานใช้ฟีเจอร์นั้นอย่างไร แล้วสุดท้ายผมก็พบว่าโค้ดของผมไม่ตอบโจทย์เป้าหมายทางธุรกิจ (business goal)
ลองยกตัวอย่างแอปปฏิทินดูครับ
ผู้ใช้คลิกวันที่ 1 มีนาคมเพื่อทำเครื่องหมายว่าเป็นวันหยุด แต่แอปกลับไปทำเครื่องหมายที่วันที่ 28 กุมภาพันธ์แทน เรื่องนี้เกิดขึ้นเพราะเรื่องเขตเวลา (timezones)
นักพัฒนาใช้ Date object ซึ่ง Date object นั้นเป็นตัวแทนของช่วงเวลาใดช่วงเวลาหนึ่งที่เฉพาะเจาะจง
ในโตเกียว เวลาเที่ยงคืนของวันที่ 1 มีนาคม ยังคงเป็นวันที่ 28 กุมภาพันธ์ในลอนดอน หากโค้ดของคุณใช้เมธอด UTC ในการบันทึกวันที่ วันที่ก็จะคลาดเคลื่อนไป
บั๊กนี้เกิดขึ้นเพราะการนำไปใช้งานในเชิงเทคนิค (technical implementation) ขัดแย้งกับตรรกะทางธุรกิจ (business logic)
ผู้ใช้คิดเป็น "วัน" ผู้ใช้ไม่ได้คิดถึงค่า UTC offset หรือ timestamp ในหน่วยมิลลิวินาที พวกเขาคิดแค่ว่า: "ฉันต้องการวันที่ 14 มีนาคม"
หากคุณต้องการให้โค้ดของคุณมีความน่าเชื่อถือ คุณต้องจำลองโดเมน (model the domain) ให้ถูกต้อง
ในปฏิทินแบบกระดาษ วันที่ก็คือ ปี เดือน และวัน มันไม่มีเรื่องเขตเวลามาเกี่ยวข้อง
คุณสามารถแก้บั๊กนี้ได้ด้วยการทำให้สอดคล้องกับ UTC หรือเวลาท้องถิ่น แต่นั่นเป็นเพียงการแก้ปัญหาที่ปลายเหตุ วิธีที่ดีกว่าคือการใช้โครงสร้างข้อมูล (data structures) ที่ไม่มีทางผิดพลาดได้
แทนที่จะใช้ Date object ให้ใช้ custom object แทน:
• ปี: 2026 • เดือน: มีนาคม • วัน: 1
วิธีนี้จะตัดเรื่องเวลาและเขตเวลาออกจากสมการ ทำให้บั๊กนี้ไม่มีทางเกิดขึ้นได้
ใช่ครับ วิธีนี้ต้องใช้แรงมากกว่าเดิม คุณต้องเขียน utility เพื่อเปรียบเทียบวันที่หรือหาจุดสิ้นสุดของเดือน และคุณยังมีเดดไลน์กับ sprint ที่ต้องกังวลอีก
แต่การจำลองโดเมนให้ถูกต้องจะช่วยปกป้องคุณจากตั๋วแจ้งปัญหา (support tickets) ที่เต็มไปด้วยความโกรธเคือง และช่วยประหยัดเวลาในการไล่แก้บั๊ก (debugging) หลายชั่วโมงในภายหลัง
ดังที่ Eric Evans กล่าวไว้ใน Domain-Driven Design:
"เพื่อให้สื่อสารได้อย่างมีประสิทธิภาพ โค้ดจะต้องตั้งอยู่บนภาษาเดียวกันกับที่ใช้ในการเขียนความต้องการ (requirements)"
เลิกคิดในฐานะโปรแกรมเมอร์เพียงอย่างเดียว แต่เริ่มคิดถึงกฎทางธุรกิจ (business rules) บ้าง
