7 นิสัยง่าย ๆ ของวิศวกรระดับท็อป 1%
(engineercodex.substack.com)- "วิธีที่โค้ดเดอร์ระดับหัวกะทิแสดงศักยภาพได้เหนือกว่าโค้ดเดอร์คนอื่น"
จงเป็นวิศวกร ไม่ใช่แค่โค้ดเดอร์ (Be an engineer, not a coder)
- วิศวกรรมคือการแก้ปัญหา
- วิศวกรที่ดีที่สุดมองว่าโค้ดเป็นเครื่องมือสำหรับบรรลุเป้าหมาย
- แม้การเขียนโค้ดจะเป็นเรื่องสนุก แต่การเขียนโค้ดที่ไร้จุดหมายไม่มีความหมาย แทนที่จะเป็นเช่นนั้น โค้ดควรถูกใช้เพื่อออกแบบโซลูชันสำหรับผู้ใช้
- การเขียนโค้ดคือการแสวงหาความคิดสร้างสรรค์! ความคิดสร้างสรรค์มักเกิดขึ้นภายใต้ข้อจำกัด เมื่อเพิ่ม "ข้อจำกัด" ว่ามีปัญหาชัดเจนที่ต้องแก้ วิศวกรก็จะมีอิสระในการสำรวจและสร้างโซลูชันในแบบที่ตนเห็นว่าเหมาะสม
- วิศวกรที่ดีที่สุดยึดผลิตภัณฑ์เป็นศูนย์กลาง และเหนือสิ่งอื่นใดให้ความสำคัญกับการแก้ปัญหาเพื่อมนุษย์เป็นอันดับแรก ซึ่งนำไปสู่ขั้นถัดไป
เขียนโค้ดเพื่อมนุษย์ ไม่ใช่เพื่อคอมพิวเตอร์ (Code for the human, not the computer)
"ใคร ๆ ก็เขียนโค้ดให้คอมพิวเตอร์เข้าใจได้ แต่โปรแกรมเมอร์ที่ยอดเยี่ยมจะเขียนโค้ดให้มนุษย์เข้าใจได้" - Martin Fowler
- โค้ดไม่ได้มีไว้สำหรับคอมพิวเตอร์เท่านั้น แต่มีไว้สำหรับมนุษย์ด้วย
- โค้ดมีไว้สำหรับวิศวกรในทีมเดียวกันที่ต้องอ่าน บำรุงรักษา และต่อยอดบนโค้ดของคุณ
- โค้ดมีไว้สำหรับผู้ใช้ ไม่ว่าจะเป็นเด็กเล็กที่ใช้โทรศัพท์มือถือ นักพัฒนาที่เรียก API หรือตัวคุณเอง
- วิศวกรที่ดีที่สุดประเมินคุณค่าของโค้ดโดยคำนึงถึงผู้ใช้ทุกกลุ่มอยู่เสมอ
- หากพวกเขาไม่สามารถทำให้ลูกค้าสักกลุ่มหนึ่งพึงพอใจได้ โค้ดนั้นก็จะไม่ถูกนำขึ้น production
แยกตัวเองออกจากตัวโค้ด (Detach from the code itself)
- วิศวกรที่ยอดเยี่ยมจะไม่ยึดติดกับตัวโค้ดมากเกินไป
- หากผลลัพธ์สุดท้ายจะดีขึ้นโดยรวม พวกเขาก็ไม่กลัวที่จะลบโค้ดที่ทำไปแล้ว 90% แล้วเริ่มใหม่
- พวกเขาเปิดรับฟีดแบ็กอย่างจริงจัง เพราะโค้ดไม่ใช่เรื่องส่วนตัว
- โค้ดไม่สมบูรณ์แบบ และไม่มีใครสนใจโค้ดที่สมบูรณ์แบบ สิ่งที่คนสนใจคือโค้ดที่สร้างความเปลี่ยนแปลง
- วิธีที่ดีที่สุดในการฝึกไม่ให้ยึดติดกับโค้ดคือ "ตระหนักว่าอีก 20 ปีข้างหน้า โค้ดส่วนใหญ่ของคุณมีแนวโน้มจะกลายเป็น technical debt หรือไม่ก็เลิกใช้งานไปแล้ว หรือถูกเขียนใหม่"
ใช้มาตรฐานที่สม่ำเสมอ (Use consistent standards)
- เวลาเขียนโค้ดให้ยึดมาตรฐานและสไตล์การเขียนโค้ดที่สม่ำเสมอ
- การรักษาความสม่ำเสมอ (Consistency) จะช่วยให้ทั้งตัวคุณในอนาคตและเพื่อนร่วมทีมอ่านและเข้าใจโค้ดได้ง่ายขึ้น
- การใช้ style guide ที่สม่ำเสมอช่วยให้ทั้งทีมและ codebase ขยายตัวได้ง่ายขึ้น
- นี่คือวิธีที่บริษัทอย่าง Meta/Google สามารถปล่อยโค้ดจำนวนมากได้อย่างรวดเร็ว โดยที่ codebase ไม่กลายเป็นสิ่งที่อ่านหรือบำรุงรักษาไม่ได้เมื่อเวลาผ่านไป
- ทุกบริษัทที่มีผลงานยอดเยี่ยมล้วนทำให้ style guide กลายเป็นส่วนหนึ่งของการทำงาน เข้าใจข้อดีของมัน และพยายามปฏิบัติตามให้มากที่สุด
- Google เปิดซอร์ส style guide บางส่วนไว้แล้ว
- Meta มี C++ style guide ในบางโปรเจกต์โอเพนซอร์สของตน
- เคล็ดลับ: การตั้งค่าให้ Linter จัดรูปแบบโค้ดสำหรับทีมของคุณเป็นสิ่งที่คุ้มค่ากับเวลาที่ลงทุนอย่างแน่นอน
เขียนโค้ดให้เรียบง่าย (Write simple code)
- วิศวกรระดับหัวกะทิทุกคนที่ผมรู้จัก อาจต้องผ่านกระบวนการสร้างที่ซับซ้อน แต่สุดท้ายแล้วจะสร้างโค้ดที่อ่านและเข้าใจง่าย
- คำอธิบายที่ดีที่สุดที่ผมมีต่อเรื่องนี้คือ โค้ดของพวกเขา "น่าพึงพอใจในเชิงสุนทรียะ"
- โค้ดของพวกเขาสะอาด เป็นระเบียบ และมีตรรกะ (clean, organized, and logical)
- ทุกการตัดสินใจในโค้ดมีเหตุผล และถ้าไม่ชัดเจนก็มีการเขียนเอกสารไว้ในโค้ดอย่างดี
- วิธีที่ดีในการเขียนโค้ดสะอาดคือทำตามหลักการอย่าง SOLID แม้แรกเริ่มจะถูกออกแบบโดยคำนึงถึง OOP (object-oriented programming) แต่ก็สามารถขยายใช้กับการเขียนโปรแกรมทั่วไปได้
- Single Responsibility: หนึ่งคลาสควรมีเพียงหนึ่งความรับผิดชอบ
- Open-Closed: วัตถุซอฟต์แวร์ (คลาส โมดูล ฯลฯ) ควรเปิดรับการขยาย แต่ปิดรับการแก้ไข เพื่อให้โค้ดมีความคาดเดาได้และบำรุงรักษาได้
- Liskov Substitution: ชนิดย่อยควรถูกแทนที่ด้วยชนิดฐานได้โดยไม่กระทบความถูกต้องของโปรแกรม
- Interface Segregation: โค้ดไม่ควรผูกติดกับอินเทอร์เฟซขนาดใหญ่ที่ไม่ได้ใช้งานทั้งหมด แต่ควรเปิดให้แพ็กเกจมีและ import อินเทอร์เฟซย่อยที่เฉพาะเจาะจงกว่าได้
- Dependency Inversion: โมดูลระดับบนไม่ควรขึ้นต่อโมดูลระดับล่าง แต่ทั้งสองควรขึ้นต่อ abstraction เพื่อส่งเสริมการออกแบบระบบที่ยืดหยุ่นและแยกส่วนมากขึ้น
- ตัวอย่างหนึ่งคือการตั้งชื่อ (Naming): ชื่อที่ดีไม่มีค่าแบบ magic value แยกความแตกต่างได้ชัดเจน และสื่อถึงชื่อฟังก์ชันกับตัวแปรที่เข้าใจง่าย
อย่ายอมให้มีเรื่องไม่คาดคิด (Don’t allow surprises)
- โค้ดไม่ควรสร้างผลลัพธ์ที่ไม่คาดคิด ซึ่งทำได้ด้วยการยึดหลักการเขียนโค้ดและเขียนการทดสอบที่เหมาะสม
- โค้ดที่ดีต้องคาดเดาได้
- การทดสอบช่วยเสริมความชัดเจนและความคาดเดาได้ของโค้ด และสร้างความมั่นใจ ด้วย automated tests ที่ดี ทีมสามารถเปลี่ยนโค้ดได้โดยไม่ต้องกังวลว่าจะพังในส่วนที่มองไม่เห็น
- ประเภทของการทดสอบบางส่วน
- unit test สำหรับคอมโพเนนต์เดี่ยวและฟังก์ชันที่แยกขาดจากกัน
- integration test สำหรับปฏิสัมพันธ์ระหว่างหลายคอมโพเนนต์
- end-to-end test ที่ประเมินการทำงานของทั้งระบบจากมุมมองของผู้ใช้
- การทดสอบควรเรียบง่าย เมื่ออ่านผลทดสอบที่ล้มเหลวแล้วควรเข้าใจได้ง่ายว่าอะไรผิดพลาด
- การรู้ด้วยว่าอะไรไม่ควรทดสอบก็สำคัญเช่นกัน
- ตัวอย่างเช่น หากความพยายามของ end-to-end test มากกว่าประโยชน์จริงของโปรแกรม การทดสอบอาจถูกแทนที่ด้วยการเขียนเอกสารอย่างรอบคอบ การมอนิเตอร์ และการส่งการแจ้งเตือนไปยังคนที่เหมาะสม (เช่น code owner)
- นอกจากนี้ การทดสอบไม่ควรทดสอบรายละเอียดระดับ implementation ในโค้ด เช่น การทดสอบ CSS selector เฉพาะในโค้ดฝั่ง frontend หรือการใช้เพียง data attributes หรือ screenshot tests เท่านั้น
สื่อสารให้บ่อย (Communicate often)
- ระบบที่ยอดเยี่ยมไม่ได้ถูกสร้างขึ้นเพียงลำพัง วิศวกรที่ยอดเยี่ยมผ่านการ review การออกแบบ ขอฟีดแบ็ก และทำซ้ำกับแบบร่างเริ่มต้นของโค้ดอยู่เสมอ
- ทุกคนล้วนมีช่องว่างในความรู้ของตัวเองที่คนอื่นช่วยเติมเต็มได้ มุมมองใหม่มักช่วยให้โค้ดชัดเจนขึ้น หรือเสนอแนวทางใหม่ที่ก่อนหน้านี้อาจไม่เคยนึกถึง
- วิศวกรที่ดีที่สุดให้ความสำคัญกับการสื่อสารและการทำงานร่วมกัน และไม่กลัวที่จะใช้เวลาทำงานร่วมกับผู้อื่นเพื่อให้ได้ผลลัพธ์สุดท้ายที่ดีกว่า
- มันอาจง่ายแค่ส่ง ping หาเพื่อนร่วมทีมเพื่อรีวิวเอกสารอย่างรวดเร็ว หรือเพิ่ม code reviewer ให้กับ pull request ที่สำคัญ
เขียนโค้ดให้เร็ว... และช้า (Code fast… and slow)
- วิศวกรที่เก่งที่สุดเท่าที่ผมรู้จักทำโปรเจกต์เสร็จได้เร็ว แต่เขียนโค้ดช้า
- ฟังดูแปลกใช่ไหม?
- หลักการและนิสัยทั้งหมดข้างต้นเพิ่มเวลาให้กับช่วงแรกของการเขียนโค้ดมากขึ้น แต่ด้วยหลักการและนิสัยเหล่านี้ วิศวกรสามารถพาโปรเจกต์คืบหน้าไปทีละขั้นได้
- การใช้มาตรฐาน การทดสอบให้ถูกต้อง การใช้หลักการ และการสื่อสารบ่อย ๆ ช่วยประหยัดเวลาได้มากกว่าในระยะยาว
- ตอนที่ผมเป็นอินเทิร์นและวิศวกรจูเนียร์ ผมเคยเจอกับตัวเอง และวิศวกรอีกหลายคนก็คงเหมือนกัน คือรีบก้าวไปข้างหน้า 3 ก้าวจนชนอุปสรรค แล้วต้องถอยหลัง 5 ก้าว
อย่าทำตามกฎแบบมืดบอด (Don’t follow rules blindly)
- "กฎ" และ "หลักการ" ข้างต้นเป็นเพียงแนวทางเท่านั้น ไม่ใช่ว่าทุกอย่างจะเข้ากับแนวทางได้อย่างพอดีเป๊ะ
- บางครั้งโค้ดที่คุณกำลังเขียนอาจเป็นสี่เหลี่ยมที่ใส่ลงในวงกลมไม่ได้ แต่ก็ไม่เป็นไร
- ในกรณีนี้ให้บันทึกเอกสารไว้ว่าทำไมโค้ดจึงถูกเขียนในรูปแบบนั้น
- มิฉะนั้น วันหนึ่งใครบางคนรวมถึงตัวคุณในอนาคตอาจมองโค้ดนั้นแล้วคิดว่า "ว้าว ตอนนั้นฉันโง่มากเลย ทำไมสิ่งนี้ถึงไม่ทำตามมาตรฐานของเรา?"
- แล้วพวกเขาก็จะใช้เวลา 20 ชั่วโมงเขียนโค้ดใหม่ให้ตรงตามมาตรฐาน เพื่อไปจบที่ข้อสรุปเดิมอีกครั้ง
- ความจริงของการพัฒนาซอฟต์แวร์คือ ไม่ใช่ทุกโค้ดจะสะอาดหรือทำตามกฎได้อย่างสมบูรณ์แบบ
- แต่โค้ดที่สม่ำเสมอ สะอาด เข้าใจง่าย ทดสอบได้ และมีคุณค่านั้นมีอยู่จริง
- รูปแบบอื่น ๆ ที่ผมพบในวิศวกรที่ดีที่สุด
- มีความรู้เชิงลึกอย่างน้อยหนึ่งโดเมน วิศวกรทุกคนที่ผมบันทึกไว้ต่างขึ้นมาอยู่ในระดับแถวหน้าของสายงาน เพราะพวกเขาโฟกัสและกลายเป็นผู้เชี่ยวชาญในด้านเฉพาะ เช่น frontend infrastructure, distributed systems หรือ UI ที่สะอาด
- ทำการตลาดให้ตัวเองอย่างเหมาะสมและสม่ำเสมอ วิศวกรเหล่านี้ไม่ได้ซ่อนตัวอยู่ในมุมที่ไม่มีใครเห็น ทุกคนที่ทำงานร่วมกับพวกเขารู้ถึงคุณค่าและความเชี่ยวชาญของพวกเขา ซึ่งเป็นผลจากการสื่อสารตัวเองอย่างเหมาะสมและการทำโปรเจกต์ที่สร้างอิทธิพล
11 ความคิดเห็น
ได้มุมมองที่ดีมากเลยครับ ขอบคุณนะครับ :)
เป็นบทความที่ดีนะ!
แม้ทักษะทางเทคนิคจะสำคัญ แต่ก็ทำให้ได้คิดอีกครั้งว่าสิ่งสำคัญจริง ๆ คือการสร้างผลิตภัณฑ์ที่เป็นประโยชน์ต่อผู้คน!!!
ขอบคุณสำหรับบทความดี ๆ ครับ!
พอมาดูอีกทีบอกว่าเป็น 7 นิสัย แต่เนื้อหาจริงมี 9 ข้อนะ 555
ผมก็นับดูเหมือนกัน.. อันสุดท้ายกับอันแรกน่าจะเป็นแค่ชื่อเรื่องเฉย ๆ ครับ! 555
ว้าว เป็นบทความที่ดีมากและเห็นด้วยกับแทบทั้งหมดเลย ฮ่าๆ
คอนเทนต์ระดับตำนานที่สุดในบรรดาบทความแนวนี้ที่เคยเห็นมาจนถึงตอนนี้
ถ้าลองทำให้เป็นภาพรวมกว้างขึ้นอีกสักหน่อย ก็เป็นบทความดี ๆ ที่น่าจะช่วยทุกคนได้
นี่แทบจะไม่ใช่สรุปแล้ว แต่เหมือนแปลมาเลย... ขอบคุณมากสำหรับสรุปนะครับ
เป็นบทความที่น่าอ่านทบทวนได้เรื่อย ๆ เลยครับ
จริงเลยครับ 555 ผมเองก็ว่าจะกลับมาอ่านซ้ำเรื่อยๆ เหมือนกัน