หมายเหตุการย้ายบทความ: บทความนี้เผยแพร่ครั้งแรกเมื่อ 2024-11-18 บน Medium และย้ายมาเผยแพร่ในบล็อกนี้เมื่อ 2026-10-18 โดยคงเนื้อหาและบริบทเดิม ตัวอย่างโค้ดไม่ได้ผ่านการรันทดสอบใหม่

Photo by David Clode on Unsplash
สวัสดีครับทุกคน กลับมาพบกันอีกครั้งหลังจากห่างหายไปสักพัก ในตอนที่แล้ว เราได้พูดถึงหลักการข้อแรกกันไปอย่างละเอียด นั่นคือ “Understandability” หรือความสามารถในการทำความเข้าใจ ซึ่งเนื้อหาค่อนข้างยาวและลึกซึ้งเลย
วันนี้ เราจะมาต่อกันด้วยหลักการข้ออื่นๆ กันครับ แต่ก่อนที่จะเริ่ม ผมอยากให้เราทบทวนกันสักนิดว่าหลักการในการตั้งชื่อที่ดีนั้นมีทั้งหมดกี่ข้อ และมีอะไรบ้าง เพื่อให้เราไม่หลงทางและเข้าใจภาพรวมได้ชัดเจนมากขึ้น (จะได้รู้ว่าเราจะไปจบกันที่ตรงไหนครับ ฮ่าๆ) เรามาทบทวนจาก list of principle ด้านล่างกันก่อนเลยครับ
List of principle
- Understandability: ชื่อที่ดีควรอธิบายสิ่งที่มันจะสื่อถึงได้ดี
- Conciseness: ชื่อที่ดีควรใช้แค่คำที่จำเป็นในการอธิบายตัวมันเอง
- Consistency: ชื่อที่ดีควรมีความสม่ำเสมอของรูปแบบในการตั้งชื่อ
- Distinguishability: ชื่อที่ดีควรแยกความแตกต่างจากชื่ออื่นๆได้ง่าย
จาก list ด้านบน วันนี้เราจะมาลุยกันต่อที่เรื่อง Conciseness ครับ ส่วนใครอยากทบทวน ก็สามารถย้อนกลับไปอ่านดึงความจำได้อีกรอบตามลิงก์ด้านล่างครับ
- Part 1 — Introduction
- Part 2 — Why is naming hard?
- Part 3 — List of Principles: 1. Understandability
Conciseness
หนังสือได้บอกไว้ว่า Conciseness คือ “A name should use only the words necessary to communicate the concept it represents!” ละมันคือยังไง
ผมคิดว่าน่าจะพอสรุปได้ว่า ชื่อที่ดีควรจะใช้เฉพาะ “คำ” ที่จำเป็นในการสื่อสารหรืออธิบายสิ่งที่ชื่อนั้นเป็นตัวแทน
จากคำอธิบายคร่าวๆด้านบน เราจะมี quote คมๆประโยคนึงกล่าวไว้ว่า
The more you say, the less people remember. — Francois Fenelon
หรือ พูดไปสองไพเบี้ย นิ่งเสียตำลึงทอง!! ไม่ใช่ละ!!
จริงๆมันคือ “ยิ่งเราพูดมาก คนก็ยิ่งจำได้น้อยลง”
โดยใน part ของ Conciseness ได้เสริมอีกว่า “Long names waste space - ชื่อที่ยาวนั้นมันเปลืองพื้นที่” แล้วพื้นที่ที่ว่านี่คืออะไร? หนังสือได้อธิบายต่อให้ว่า ชื่อที่ยาวเกินไปนั้นทำให้เกิดการสิ้นเปลืองพื้นที่ทั้ง “ในโค้ด(ตอนที่เราเขียน)” และ “ในความคิด(ตอนที่เราจำหรือคิดเกี่ยวกับมัน)” โดยงานวิจัยตัวนึงพบว่าชื่อที่ยาวๆเนี่ย มันต้องใช้เวลามากขึ้นในการพิจารณาและทำความเข้าใจ แถมยังทำให้ความสามารถในการจดจำลดลงไปอีก เนื่องด้วยจำนวนพยางค์ที่เพิ่มขึ้น ทำให้ความจำระยะสั้นของเรานั้นถูกใช้งานมากเกินไป
อย่างไรก็ตาม โค้ดที่มีชื่อตัวระบุแบบผสมคำที่บรรยายความหมายเข้าไป จะสามารถทำให้คนอ่านเข้าใจได้เร็วกว่าชื่อสั้นๆ ที่ใช้คำเพียงคำเดียว ดังนั้น ชื่อที่สั้นแต่ไม่สื่อความหมายจึงลดความสามารถในการทำความเข้าใจของคนอ่านไปด้วย
การสร้างสมดุลระหว่างความยาวและความสื่อความหมายนั้นแตกต่างกันไปตามระดับประสบการณ์ โดยโปรแกรมเมอร์ที่มีประสบการณ์หรือพวกมือเก๋า จะได้ประโยชน์จากชื่อที่บรรยายความหมายมากกว่ามือใหม่ ทั้งนี้อาจเป็นเพราะพวกมือเก๋าสามารถเชื่อมโยงชื่อเหล่านั้นกับแนวคิดที่มีอยู่ในความจำระยะยาวได้ดีกว่า หรือมีทักษะในการจัดกลุ่มข้อมูลย่อยๆเข้าด้วยกันได้ดีกว่าโปรแกรมเมอร์มือใหม่นั่นเอง
สุดท้าย ชื่อที่ดีควรสื่อสารข้อมูลจำนวนมากให้กับกลุ่มเป้าหมายได้ด้วยตัวอักษรจำนวนน้อย ซึ่งการที่เราย่อชื่อลงอย่างไม่ระมัดระวังอาจทำให้คนอ่านนั้นเข้าใจได้ช้าลง เราจึงต้องพิจารณาทั้งความกระชับและสื่อความหมายไปพร้อมกันครับ
Rules
กฎคร่าวๆของ Conciseness ก็จะมีอยู่ประมาณ 5 ข้อครับ ไม่เยอะเท่า Understandability ฮ่าๆ เดี๋ยวเราลองไปดูกันทีละข้อเลยดีกว่าครับ
1. Use the appropriate level of abstraction
การตั้งชื่อที่ดีเราควรจะใช้ระดับความเป็นนามธรรมให้เหมาะสม ระดับความเป็นนามธรรมของชื่อจะบ่งบอกถึงความเฉพาะเจาะจงหรือความกว้างของชื่อนั้น เราลองนึกถึงชื่อที่เฉพาะเจาะจงมากๆ เช่น validated_total_sales_per_day_and_account_data_set (เฉพาะเกิ๊น ยาวจัด) ไปจนถึงชื่อที่กว้างมาก เช่น data (นี่ก็สั้นจู๊ด) การเลือกระดับความเป็นนามธรรมให้เหมาะสมเลยเป็นสิ่งสำคัญในการตั้งชื่อที่มีประสิทธิภาพ ที่จะช่วยให้โค้ดอ่านง่ายและสื่อความหมายได้ชัดเจน
แต่ว่าแล้วเราจะรู้ได้ยังไง ว่าเราจะใช้ระดับไหนถึงจะเหมาะสม? 🤔
ในเรื่องของระดับความเป็นนามธรรม มีแนวคิดที่ชื่อว่า “บันไดแห่งความเป็นนามธรรม” ของ S. I. Hayakawato ที่จะช่วยอธิบายวิธีที่ผู้คนคิดและสื่อสารในระดับความเป็นนามธรรมที่แตกต่างกัน
ตัวอย่างเช่น การเรียกวัวว่า “Bessie” อาจเหมาะสมสำหรับเจ้าของ แต่คำว่า “ปศุสัตว์” อาจเหมาะสมกว่าสำหรับเจ้าของบริษัทเกษตรขนาดใหญ่ เช่นเดียวกับเวลาที่เราแนะนำตัว เราต้องเลือกระดับข้อมูลที่เหมาะสมกับสถานการณ์และผู้ฟัง (ใครสนใจไปอ่านบันได้แห่งความเป็นนามธรรมของ S.I. Hayakawato ต่อ ก็ลองจิ้มลิงก์นี้ดูได้นะครับ link)

Ladder of Abstraction from Naming Things
ในการเลือกระดับความเป็นนามธรรมที่เหมาะสมสำหรับการตั้งชื่อนั้น เราควรรู้จักคนอ่านและข้อมูลที่เกี่ยวข้องกับพวกเขา หลีกเลี่ยงการใช้ชื่อที่เฉพาะเจาะจงเกินไปจนให้ข้อมูลที่ไม่เกี่ยวข้อง หรือกว้างเกินไปจนให้ข้อมูลน้อยเกินไป กฎทั่วไปคือ เราควรใช้ชื่อที่แสดงเจตนาของแนวคิด: สิ่งนี้มันถูกใช้เพื่ออะไร ไม่ใช่วิธีการทำงาน
ตัวอย่างเช่น ในการเขียน method ที่ลบช่องว่างออกจากหมายเลขโทรศัพท์ ควรเลือกชื่อที่สื่อถึงวัตถุประสงค์มากกว่าวิธีการทำงาน เช่น format(phone_number) แทนที่จะเป็น strip(phone_number) ชื่อ format บอกคนอ่านว่า method นี้จะช่วยจัดรูปแบบหมายเลขโทรศัพท์ให้ตรงตามสเป็ค ซึ่งน่าจะตรงกับความคาดหวังของคนอ่านมากที่สุด โดยที่เราไม่จำเป็นต้องเปิดเผยรายละเอียดการทำงานภายในที่อาจเปลี่ยนแปลงในอนาคต ลองดูจากตัวอย่างด้านล่าง
# จุดประสงค์คือสร้าง method ที่มีการจัดรูปแบบเบอร์โทรศัพท์ที่รับเข้ามาให้ถูกต้อง
1. process(phone_number)
# พอใช้ process ก็ทำให้คนอ่านงงๆนิดนึง เพราะมีความไม่เกี่ยวข้องอยู่ ไม่รู้ด้วยว่าจะเอา phone_number ไปทำอะไรต่อ
2. format(phone_number)
# format อันนี้โอเคเลย คนอ่านรู้ ว่าโยน phone_number เขาไปตัว method ต้องไปจัดการรูปแบบให้แน่ๆ
3. trim_whitespace(phone_number)
# trim_whitespace อันนี้ก็ไม่ได้แย่ แถมบอกด้วยว่าจะทำอะไร แต่มันก็เฉพาะเจาะจงจนเกินไป ไม่ได้ตรงกับจุดประสงค์เรา
4. strip(phone_number)
# strip บอกชัดเหมือนกันว่าจะทำอะไรกับเบอร์ แต่จุดประสงค์ของเรามันคือการจัดฟอร์แมท
ดังนั้นการใช้บันไดแห่งความเป็นนามธรรมจะช่วยให้เราพิจารณาชื่อหลายๆ แบบ และเลือกชื่อที่ให้ข้อมูลที่เกี่ยวข้องมากที่สุดกับคนอ่าน โดยที่เราไม่จำเป็นต้องอธิบายถึงวิธีการทำงานภายใน ซึ่งสามารถดูได้จากโค้ดการทำงานอยู่แล้ว การเลือกชื่อที่เหมาะสมจึงเป็นการสร้างสมดุลระหว่างความชัดเจนและความยืดหยุ่น เพื่อให้โค้ดสามารถอ่านและบำรุงรักษาได้ง่ายในระยะยาว ซึ่งช่วยเพิ่มประสิทธิภาพในการทำงานร่วมกันของทีมพัฒนานั่นเองครับ
2. Use words with rich meaning
ชื่อที่ดีต้องตั้งชื่อให้ดูรวย!! ผิดดดด แฮ่ ชื่อที่ดีเราควรตั้งชื่อให้สื่อความหมายได้มากที่สุดในจำนวนของแต่ละตัวอักษร ควรเป็นคำที่ใช้สื่อสารข้อมูลที่เกี่ยวข้องกับระบบหรือโปรแกรมที่เรากำลังจะทำ เช่น สมมติเรากำลังทำแอพฟังเพลง แทนที่เราจะใช้ตัวแปรที่ชื่อว่า SongCollection เราก็สามารถที่จะใช้คำว่า Album ซึ่งเป็นคำที่สั้นและสื่อความหมายได้มากกว่า
แต่ว่าการตั้งชื่อให้ได้ความหมายหรือเข้าใจคำศัพท์ที่ตรงกับปัญหานั้นก็มีความสำคัญ เช่นบางปัญหาที่เราเจอ เราอาจจะใช้คำว่า Subtask แทนที่การใช้ ChildTask ก็จะเหมาะสมและคุ้นเคยมากกว่า
# Bad
SongCollection
ChildTask
# Good
Album
Subtask
ทีนี้พอเรามองต่อมาที่ตัว method ที่ส่วนใหญ่เรามันจะใส่คำกริยาเข้าไปด้วย เราก็ต้องมาพิจารณาด้วยว่า ตัวการทำงานข้างใน method นั้นทำอะไรบ้าง บางครั้งเราอาจจะตั้งชื่อโดยใช้ “get” นำหน้ามาตลอด เราอาจจะต้องเปลี่ยนมาเป็น “fetch”, “find”, หรือ “generate”, “calculate”, “load” และอื่นๆ ตามบริบทของการทำงานด้านในของ method นั้นด้วย รวมถึงเราต้องใช้คำเหล่านี้ให้สม่ำเสมอกัน ไม่ใช่จุดนึงเรียก “get_xxx” แต่อีกจุดไปใช้ “fetch_yyy” ทั้งๆที่การทำงานด้านในเหมือนๆกันเพียงแค่เรียกใช้หรือดึงข้อมูลคนละอย่างกันเท่านั้น
# Bad
get_user(user_id)
# Good
fetch_user(user_id)
3. Omit metadata
ในการตั้งชื่อบางครั้ง เราสามารถตั้งชื่อได้โดยไม่ต้องมีข้อมูลประเภท metadata อยู่ในชื่อเลยก็ได้ เพราะคนอ่านจะสามารถเข้าใจชื่อนั้นได้โดยที่เราไม่ต้องระบุประเภทหรือขอบเขตของมันเลย เราอาจจะเคยผ่านๆตาเจ้ากฎ Hungarian Notation ตัวอย่างเช่น str FirstName, validate Fn แต่พอเราสังเกตุดีๆ เราจะพบว่าการใส่ข้อมูลพวก metadata เข้าไปจะเพิ่มความยาวและความซ้ำซ้อนโดยไม่จำเป็นครับ
# Bad
first_name_string
first_name_str
person_list
people_array
ComparisonInterface
# Good
first_name
people
Comparable
4. Omit implementation details
การรวมรายละเอียดการทำงานภายในที่ไม่จำเป็นในการตั้งชื่อ มักจะเกิดขึ้นบ่อยที่สุดในเวลาที่พวกเราตั้งชื่อ method กฎที่ดีคือการตั้งชื่อ method คือเราควรตั้งชื่อตามสิ่งที่มันทำ ไม่ใช่วิธีการที่มันทำ ตัวอย่างเช่น สมมติว่าเรากำลังเขียน method ที่ประมวลผลแถวของ CSV แบบขนาน (parallel) ซึ่งตอนที่เราตั้งชื่อเราก็รู้แหละว่ามันจะทำงานแบบไหน (ก็แบบขนานนั่นแหละ) ซึ่งมันก็เป็นวิธีการทำงานของมัน เราไม่จำเป็นที่จะต้องใส่ก็ได้ ยกตัวอย่างเช่น
# Bad
csv_processor.process_in_parallel(rows)
# Good
csv_processor.process(rows)
หรืออีกตัวอย่าง ในกรณีที่เราจำเป็นต้องรองรับทั้งการประมวลผลทั้งแบบอนุกรมและแบบขนาน วิธีที่ดีที่สุดคือการเพิ่มอาร์กิวเมนต์เข้าไป เพื่อให้ชื่อ method ได้อธิบายสิ่งที่ตัวมันเองกำลังทำเสมอ ซึ่งเจ้าตัวอาร์กิวเมนต์นี่เอง จะช่วยเราอธิบายวิธีการทำงานของมันได้อีกทาง
# Bad
csv_processor.process_in_parallel(rows)
csv_processor.process_in_serial(rows)
# Good
csv_processor.process(rows, in_parallel=True)
csv_processor.process(rows, in_parallel=False)
การใช้อาร์กิวเมนต์แทนการสร้างหลาย method ช่วยป้องกันการเพิ่มจำนวนของ method ได้อีกด้วย ไม่ต้องคอยสร้างหลายๆอันมารองรับครับ
5. Omit unnecessary words
ชื่อที่ดีเราควรละเว้นการใส่คำที่ไม่จำเป็นเข้าไป การที่เราใส่คำที่ไม่ได้ช่วยให้คนอ่านเข้าใจง่ายขึ้นอย่างมีนัยสำคัญนั้น ไม่ควรใส่เข้าไปในชื่อบนโค้ดของเรา ยกตัวอย่างเช่น เรามี class User ซึ่งมี method delete_now เราเห็นอะไรแปลกๆไหม? คืออ่านปุ๊บเราน่าจะรู้สึกเลยว่าคำว่า “now” เนี่ย มันไม่จำเป็นต้องใส่เข้ามาก็ได้ เพราะโดยคนอ่านส่วนใหญ่ เขาจะเข้าใจอยู่แล้วว่าเวลาที่เรียก method ที่ชื่อ delete มันก็จะทำการลบอะไรสักอย่างทันทีอยู่แล้ว
หรืออีกหนึ่งตัวอย่างเกี่ยวกับตัวแปรประเภท Boolean (true or false) เราไม่ควรจะมีคำนำหน้า (prefix) ที่เป็นไปในเชิงลบ เช่น “not” หรือ “invalid” ซึ่งพวก prefix ที่เป็นเชิงลบพวกนี้เนี่ย นอกจากที่จะเพิ่มความยาวโดยไม่ค่อยเพิ่มความหมายเท่าไหร่แล้ว ยังทำให้มีโอกาสที่จะเกิดความหมายซ้ำซ้อนได้อีก นึกภาพเรามีตัวแปรชื่อ not_prepared ที่มีค่าเป็น false มันก็จะรู้สึกเอ๊ะแปลกๆ แถมให้ต้องคิดให้ดีอีกรอบตอนอ่านอีก ดังนั้นชื่อ Boolean ที่ดีเราควรจะตั้งให้เป็นเชิงบวกอยู่เสมอ
Conclusion
จาก 5 ข้อที่ผ่านมาของ Conciseness หรือ ความกระชับนั้น เราจะพบว่า การตั้งชื่อที่กระชับคือการตั้งชื่อที่สื่อสารข้อมูลที่มากที่สุดได้ด้วยจำนวนคำที่น้อยที่สุด โดยเราก็ต้องคำนึงระดับของนามธรรมที่เหมาะสม การเลือกใช้คำที่มีความหมายลึกซึ้ง การหลีกเลี่ยงการใส่คำที่ไม่จำเป็นหรือแม้แต่คำที่อาจทำให้เกิดความหมายซ้ำซ้อนได้ เราเลยต้องโฟกัสไปที่คนอ่านเป็นหลักและเน้นไปที่วัตถุประสงค์ของสิ่งที่เรากำลังจะสื่อถึงครับ
ก็จบไปกันอีกหนึ่ง Principle สำหรับเรื่องความกระชับ ผมมองว่าเรื่องนี้ก็น่าสนใจมากๆเหมือนกัน พออ่านจบรอบแรก ก็รู้สึกว่ามันมีหลายอย่างที่เราคุ้นตารวมถึงบาปที่เคยก่อไว้ในโค้ดเก่าๆของเราเองด้วย
สุดท้ายนี้… ผมจะสรุปเสร็จครบทุกบทกี่โมงงงงงครับบบบบ ฮ่าๆ หวังว่าจะไม่ทิ้งกันไปก่อน ผมจะรีบสรุปให้จบเร็วๆครับ ถือว่าตัวผมเองได้อ่านทบทวนอีกรอบด้วย
ยังไงก็ ชอบกดไลท์ ใช่กดรีพอร์ทเหมือนเดิมครับ 55+
ขอบคุณทุกคนที่อ่านมาจนจบครับ
อยากให้ทุกคนสนุกกับการเขียนโค้ดครับ
Be Lazy & Happy Coding 🤤🖥🤗