- รสนิยมทางเทคนิค เป็นแนวคิดที่ต่างจากความสามารถทางเทคนิค โดยแม้จะมีความสามารถสูงก็อาจมีรสนิยมที่ไม่ดีได้ และแม้จะยังไม่เก่งมากก็อาจมีรสนิยมที่ดีได้
- รสนิยมของวิศวกรซอฟต์แวร์หมายถึง ความสามารถในการเลือกคุณค่าทางวิศวกรรมที่เหมาะกับโปรเจ็กต์
- สิ่งนี้แสดงออกผ่านความรู้สึกอย่างเช่น โค้ดแบบไหน ดูดี/ดูไม่ดี การตัดสินใจด้านการออกแบบแบบใดที่ให้ความรู้สึกน่าพอใจ และปัญหาแบบใดที่เราให้ความสำคัญเป็นพิเศษ ซึ่งทั้งหมดสะท้อนถึง ชุดของคุณค่าทางวิศวกรรมที่ตนเองให้ความสำคัญ
- ทุกการตัดสินใจในวิศวกรรมซอฟต์แวร์คือความต่อเนื่องของ trade-off โดยวิศวกรที่ยังไม่เติบโตมักมองแนวทางบางอย่างเป็นความจริงสัมบูรณ์ แต่วิศวกรที่เติบโตแล้วจะ ปรับสมดุลคุณค่าอย่างยืดหยุ่นตามบริบท
- รสนิยมที่ดีคือความสามารถในการเลือก ลำดับความสำคัญของคุณค่า ให้เหมาะกับโปรเจ็กต์เฉพาะหน้า ส่วนรสนิยมที่ไม่ดีมักปรากฏในรูปของ ความแข็งทื่อ ที่ยึดติดกับมาตรฐานสัมบูรณ์อย่าง "best practice"
- รสนิยมสั่งสมได้จาก ประสบการณ์ในโปรเจ็กต์ที่หลากหลาย และ วิธีคิดที่เปิดกว้าง และท้ายที่สุดความมีหรือไม่มี รสนิยมที่ดี จะเผยออกมาผ่านความสำเร็จของโปรเจ็กต์
ความต่างระหว่างรสนิยมทางเทคนิคกับความสามารถ
- รสนิยมทางเทคนิค ไม่ได้สอดคล้องกับความสามารถที่ยอดเยี่ยมเสมอไป
- เหมือนกับที่ใคร ๆ ก็แยกอาหารอร่อยกับอาหารไม่อร่อยได้โดยไม่จำเป็นต้องทำอาหารเก่ง ในซอฟต์แวร์เอง รสนิยมก็มักก่อตัวก่อนความสามารถ
- สิ่งที่วิศวกรคิดว่าโค้ดแบบไหน "ดูดี" หรือ "ดูไม่ค่อยดี" สะท้อนรสนิยมของเขา
- การรู้สึกพอใจกับการตัดสินใจด้านการออกแบบบางแบบ และการใส่ใจปัญหาบางอย่างมากกว่าปัญหาอื่น ก็ ทำงานเป็นส่วนหนึ่งของรสนิยม
- ความสามารถทางเทคนิคเติบโตได้ผ่านการฝึกฝนและการเรียนรู้ซ้ำ ๆ แต่รสนิยมพัฒนาในแบบที่ คลุมเครือและอาศัยสัญชาตญาณมากกว่า
-
ตัวชี้วัดของรสนิยมเชิงวิศวกรรม
- การรู้สึกว่า "โค้ดนี้ดูดี/ดูไม่ดี"
- ความพึงพอใจอย่างมากหรือความเฉยเมยต่อการตัดสินใจด้านการออกแบบบางอย่าง
- ปัญหาซอฟต์แวร์ที่ยังค้างคาใจแม้หลังเลิกงาน เทียบกับปัญหาที่ไม่ได้ใส่ใจนัก
- รสนิยมคือ ความสามารถในการยึดถือคุณค่าทางวิศวกรรมที่เหมาะกับโปรเจ็กต์ปัจจุบัน
การแยกความสามารถออกจากรสนิยม
- มีคำถามว่าโค้ดที่ "ดูดี" จำเป็นต้องเป็นโค้ดที่ดีกว่าจริงหรือไม่
- ตัวอย่าง: คนที่ชอบ
map/filter อาจให้ความสำคัญกับความอ่านง่ายของโค้ดและ pure functions ส่วนคนที่ให้ความสำคัญกับ for loop อาจให้ความสำคัญกับประสิทธิภาพและการขยายแบบตรงไปตรงมา
- นี่ไม่ใช่เรื่องของถูกหรือผิด แต่คือ ความแตกต่างของคุณค่าที่ให้ความสำคัญ
- เพราะแต่ละภาษาและบริบทต่างก็มี ข้อดีข้อเสียของตัวเอง การเลือกแบบใดจึงไม่ได้ดีกว่าเสมอไป
- วิศวกรแต่ละคนให้ความสำคัญกับคุณค่าคนละแบบ จึงทำให้ ความชอบแตกต่างกัน
รสนิยมเชิงวิศวกรรมคืออะไร
- การตัดสินใจเกือบทั้งหมดในวิศวกรรมซอฟต์แวร์คือ การหาสมดุลระหว่างคุณค่าที่ขัดแย้งกัน (trade-off)
- วิศวกรที่ยังไม่ชำนาญมักยึดติดกับรสนิยมของตัวเองมากเกินไป
- วิศวกรที่เติบโตแล้ว จะมองเห็นข้อดีจากหลายมุมมองและให้ความสำคัญกับการเลือกที่เหมาะกับสถานการณ์ปัจจุบัน
- สิ่งสำคัญไม่ใช่ว่า X (เทคโนโลยี) กับ Y (เทคโนโลยี) อะไรดีกว่า แต่คือ การตัดสินว่าในโปรเจ็กต์ปัจจุบัน ข้อดีของ X จำเป็นมากกว่าของ Y หรือไม่
-
ตัวอย่างของคุณค่าทางวิศวกรรม
- Resiliency: ระบบยังทำงานได้ดีหรือไม่เมื่อเกิดความขัดข้องหรือปัญหาเครือข่าย
- Speed: มีประสิทธิภาพใกล้ขีดจำกัดทางทฤษฎีหรือไม่ มีงานที่ไม่จำเป็นมากเกินไปหรือไม่
- Readability: วิศวกรใหม่สามารถทำความเข้าใจและปรับตัวได้รวดเร็วหรือไม่ ฟังก์ชันสั้นและชัดเจนหรือไม่
- Correctness: มีการจำลองสถานะที่ผิดพลาดได้หรือไม่ มี tests, types,
assert ฯลฯ เพียงพอหรือไม่ ไปจนถึงมีการทำ formal verification หรือไม่
- Flexibility: ระบบขยายต่อได้ง่ายหรือไม่ การเปลี่ยนแปลงนำไปใช้ได้ง่ายหรือไม่
- Portability: ผูกติดกับสภาพแวดล้อมเฉพาะหรือไม่ การเปลี่ยนสภาพแวดล้อมสำหรับ deploy ทำได้ง่ายหรือไม่
- Scalability: หากทราฟฟิกเพิ่มขึ้น 10 เท่า, 100 เท่า ระบบจะขยายหรือ auto-scale ได้หรือไม่ คอขวดอยู่ตรงไหน
- Development speed: การขยายระบบทำได้เร็วแค่ไหน วิศวกรส่วนใหญ่สามารถเข้ามาทำงานได้หรือไม่
- นอกจากนี้ยังมีคุณค่าอื่น ๆ เช่น elegance, modern-ness, การใช้โอเพนซอร์ส, ต้นทุนการบำรุงรักษา ฯลฯ
- ไม่ใช่ว่าวิศวกรทุกคนจะสนใจคุณค่าแต่ละข้อในระดับเท่ากัน
- ภาษา เฟรมเวิร์ก และแพตเทิร์นการออกแบบที่ใช้จะเปลี่ยนไปตามว่าตนเองประเมินคุณค่าใดสูงที่สุด
ลักษณะของรสนิยมที่ไม่ดี
- รสนิยมที่ไม่ดี เกิดขึ้นเมื่อคุณค่าที่ตนเองชอบ ไม่เหมาะกับโปรเจ็กต์ปัจจุบัน
- ปัญหาคือการขาดความยืดหยุ่นในการผลักดันข้อดีของเทคโนโลยีหรือวิธีการบางอย่างเข้าสู่โปรเจ็กต์ของตัวเองอย่างสม่ำเสมอ
- คำกล่าวที่ยกแต่ "best practice" อยู่เสมอมักสะท้อน การขาดการตัดสินแบบปรับให้เหมาะกับสถานการณ์
- วิศวกรที่ไม่ยืดหยุ่น อาจเหมาะกับโปรเจ็กต์บางประเภท แต่เมื่อสภาพแวดล้อมหรือลักษณะงานเปลี่ยน ก็อาจก่อปัญหาร้ายแรงได้
คุณลักษณะของรสนิยมที่ดี
- รสนิยมที่ดี คือความสามารถในการ เลือกคุณค่าทางวิศวกรรมที่ถูกต้องให้เหมาะกับสถานการณ์ปัญหา
- ต่างจากความสามารถทางเทคนิคเพียงอย่างเดียว เพราะสิ่งนี้ตรวจสอบได้จริงเฉพาะใน บริบทของโปรเจ็กต์จริงที่ซับซ้อน
- หากโปรเจ็กต์ที่รับเอาการตัดสินใจด้านการออกแบบที่ตนเห็นด้วยไปใช้นั้นดำเนินไปได้ดี ก็พอใช้วัดความเหมาะสมของรสนิยมตนเองได้
- ประสบการณ์ในโปรเจ็กต์ที่หลากหลาย และท่าทีเปิดรับคุณค่าใหม่ ๆ ในบางจังหวะ เป็นองค์ประกอบสำคัญของการเรียนรู้
- การรักษา ความยืดหยุ่น และหลีกเลี่ยงการมีอคติยึดติดกับเทคโนโลยีหรือวิธีการเฉพาะ จะช่วยให้สร้างรสนิยมที่ดีได้
บทส่งท้าย
- รสนิยมที่ดีสำคัญพอ ๆ กับความสามารถ และสามารถพัฒนาได้ผ่าน ความหลากหลาย ความยืดหยุ่น และการทบทวนตนเองระหว่างการเติบโต
- บางคนก็แสดงให้เห็นถึงรสนิยมที่ยอดเยี่ยมเกินกว่าระดับประสบการณ์ของตนได้เช่นกัน (เช่น อัจฉริยะด้านการเขียนโปรแกรมหรือสาขาอื่น)
ประเด็นอภิปรายเพิ่มเติม
- ในคอมเมนต์ของ Hacker News ก็มีความเห็นที่สงสัยแม้กระทั่งการมีอยู่ของ "รสนิยม" เอง
- บางคนอ้างว่าทุกปัญหามี คำตอบที่ถูกต้องเพียงหนึ่งเดียว แต่ผู้เขียนโต้แย้งว่าในโลกจริง มีได้หลายคำตอบ และท้ายที่สุดคุณค่าส่วนบุคคลกับบริบทต่างหากที่กำหนดการเลือก
- อีกความเห็นหนึ่งชี้ว่ามุมมองของลูกค้าและบริบททางธุรกิจก็เป็นส่วนหนึ่งของรสนิยมเช่นกัน
7 ความคิดเห็น
ดูเหมือนจะเป็นนิสัยเสียที่อาจเป็นพิษต่อทีมและโปรเจกต์ มากกว่าจะมองข้ามว่าเป็นแค่รสนิยมที่ไม่ดี
ความคิดเห็นจาก Hacker News
เคยรู้สึกว่าวิศวกรที่ยังไม่โตพอมักยึดติดกับรสนิยมของตัวเองมากเกินไป และความไม่โตพอนี้ก็อาจพบได้แม้ในวิศวกรที่มีประสบการณ์ ตอนสมัยช่วยเพื่อนทำโค้ดการบ้านคอมพิวเตอร์ ฉันเคยอยากเขียนโค้ดใหม่ทั้งหมดเพียงเพราะไม่ชอบสไตล์เดิมของพวกเขา แต่สุดท้ายก็ได้ตระหนักว่าถ้าทำแบบนั้นจะเสียเวลามากเกินไป และเพื่อนก็จะไม่เข้าใจผลงานที่ออกมา ฉันจึงช่วยโดยปรับวิธีของเพื่อนเพียงเล็กน้อย และพวกเขาก็พอใจกว่ามาก ประสบการณ์นี้ทำให้ฉันได้รู้จักมุมมองที่หลากหลาย และโค้ดของตัวเองก็ดีขึ้นด้วย จนรู้สึกว่าจริง ๆ แล้วฉันควรเป็นฝ่ายขอบคุณเพื่อนเสียด้วยซ้ำ ทุกวันนี้ฉันก็ยังทิ้งอคติได้ยาก แต่พยายามทำความเข้าใจมุมมองของอีกฝ่ายอย่างจริงจังให้มากที่สุด และบางครั้งก็ยอมรับว่าวิธีนั้นดีกว่าจริง ๆ หลักการต่าง ๆ นั้นแท้จริงแล้วค่อนข้างเป็นเรื่องอัตวิสัย ดังนั้นการพึ่งแต่หลักการตลอดเวลา จึงหมายถึงการไม่ยอมคิดถึงสถานการณ์อย่างจริงจัง และเป็นวิธีที่ขี้เกียจมากกว่า
ต่อให้วิศวกรจูเนียร์กำลังทำอะไรอย่างไม่มีประสิทธิภาพ ฉันก็ไม่เคยบอกว่าพวกเขาใช้วิธีที่ปรับแต่งมาไม่ดีพอ แต่จะถามเสมอว่าทำไมถึงทำแบบนั้น ทุกครั้งที่บทสนทนาจบลง คนใดคนหนึ่งในเราสองคนจะได้เรียนรู้อะไรบางอย่าง ฉันอาจได้รู้วิธีใหม่หรือเหตุผลของพวกเขา หรือไม่พวกเขาก็จะได้เรียนรู้ว่าทำไมวิธีนั้นถึงใช้ไม่ได้ในระยะยาว ไม่ว่าแบบไหน บทสนทนาเหล่านี้ก็ไม่เคยจบลงแบบเป็นปฏิปักษ์
ฉันคิดว่า “รสนิยมที่ดี” เกิดจากการได้สัมผัส API ที่ยอดเยี่ยมและโค้ดดี ๆ โค้ดที่ดีเป็นสิ่งที่เห็นแล้วรู้ได้ทันที และเมื่อเวลาผ่านไปเราก็ควรเขียนแบบนั้นได้ แต่ถ้าเพิ่งเข้ามาในสายนี้ก็ยากที่จะมีรสนิยมด้านการเขียนโค้ดที่ดี และต่อให้มีประสบการณ์ก็ไม่ได้แปลว่าจะมีรสนิยมนี้โดยอัตโนมัติ จึงต้องพยายามมองหา รับรู้ และเลียนแบบรสนิยมที่ดีอยู่เสมอ
ทางแก้ในการหลุดพ้นจากอคติ ความลำเอียง และกรอบความคิดที่แข็งทื่อ คือการศึกษาและสะสมประสบการณ์ที่หลากหลายนอกเหนือจากมุมมองของแต่ละคน ต้องพยายามอย่างจริงจังที่จะเข้าใจโลกจากสายตาของคนอื่น จึงจะเติบโตได้ทั้งในฐานะมนุษย์และคนทำงาน และขยายมุมมองของตัวเองได้ สำหรับวิศวกรที่สนใจหลายด้านอย่างฉัน แค่รู้ว่ามีวิธีแก้หรือมุมมองอื่นอยู่ ก็ทำให้วิธีแก้ปัญหาของฉันเปลี่ยนไป และมักนำไปสู่คำตอบที่ดีกว่าสัญชาตญาณแรกเริ่ม
นี่จึงเป็นเหตุผลว่าทำไมการลองหลาย ๆ ภาษาโปรแกรมจึงเป็นเรื่องดี เมื่อท้าทายมุมมองเดิมของตัวเองด้วยภาษาใหม่ ๆ อยู่เสมอ ก็จะมีช่วงเวลาแบบ “อ๋อ!” เกิดขึ้นไม่ขาด ตอนแรกมันอาจดูแปลกหรือดูผิด แต่ก่อนจะเข้าใจเหตุผลและวิธีการนั้นอย่างถ่องแท้ ก็ต้องยอมรับไว้ก่อนว่ามันมีเหตุผลของมัน
เป็นความเห็นที่ยอดเยี่ยม วิธีคิดแบบนี้คือสิ่งที่ฉันใช้กับคนที่ฉันรับเข้าทำงานเองหรือร่วมงานด้วย หากบรรลุเป้าหมายหรือผลลัพธ์ได้ ก็ไม่จำเป็นต้องทำตามขั้นตอนและรายละเอียดของฉันทุกอย่าง เรายอมรับได้ว่ามีหลายวิธี
ฉันคิดว่า “รสนิยมที่ดี” ในแฟชั่นไม่ได้อยู่ที่เสื้อผ้าแต่ละชิ้น แต่อยู่ที่การนำเสื้อผ้าที่แต่ละชิ้นอาจดูไม่มีความหมายอะไรนักมาจัดเข้าด้วยกันจนเกิดความรู้สึกที่ทรงพลังและกลมกลืน ฉันหวังว่าบทความนี้จะไปในทิศทางนั้น และอยากเห็นการสำรวจต่อว่า สิ่งที่วิศวกรซอฟต์แวร์ตัดสินใจด้วยรสนิยมนั้น เป็นเรื่องรสนิยมจริง ๆ หรือเป็นเพียง technical trade-off กันแน่ พูดตามตรง ฉันรู้สึกว่าบทความนี้เองก็เหมือนตัวอย่างของรสนิยมที่ไม่ดี ในแง่เนื้อหาแต่ละส่วนเขียนได้ดีพอใช้ แต่ภาพรวมกลับไม่สร้าง “ลุค” ที่เป็นหนึ่งเดียว ทำให้บทความดูแตกกระจาย ไม่ได้จะโจมตีผู้เขียน แต่อยากเสนอความเห็นเพื่อให้ดีขึ้น เพราะคิดว่าหัวข้อนี้ยอดเยี่ยมมาก
ฉันไม่เห็นด้วยกับความเห็นที่ว่าเสื้อผ้าแต่ละชิ้นไม่มีความหมายในตัวเอง เสื้อผ้ามีความหมายทางวัฒนธรรม ประวัติศาสตร์ และเชิงสัญลักษณ์อยู่แล้วแม้ก่อนจะถูกนำมาจับคู่ แฟชั่นเป็นอะไรมากกว่าการจัดชุด อีกทั้งในแฟชั่นก็มี trade-off หลายแบบเช่นกัน ทั้งการผลิต การสวมใส่ และการแมตช์
สิ่งที่คุณสงสัยเกี่ยวกับ “เรารับรู้ความงามและความสง่างามได้อย่างไร” เป็นประเด็นที่นักปรัชญาถกเถียงกันมาตั้งแต่สมัยโบราณ และกว้างใหญ่เกินกว่าจะสรุปได้ในบทความเดียว Christopher Alexander ในวงการสถาปัตยกรรมได้สำรวจเรื่องนี้ไว้อย่างลึกซึ้ง และแนวคิดของเขาก็มีอิทธิพลอย่างมากต่อสถาปัตยกรรมซอฟต์แวร์ Alexander ยืนยันว่าความงามเชิงวัตถุวิสัยมีอยู่จริง ลองดู ปาฐกถา OOPSLA ของเขา หรือ วิทยานิพนธ์ปริญญาเอก ของ Roy Fielding ก็ได้ “คุณค่า” ที่พูดถึงในบทความนี้ ถูกจัดระบบไว้อย่างเป็นแบบแผนมากกว่าในวิทยานิพนธ์ของ Fielding ภายใต้ชื่อ “คุณลักษณะทางสถาปัตยกรรม”
น่าสนุกตรงที่ ฉันกลับคิดว่าบทความนี้เป็นงานเขียนชั้นยอดที่พบได้ยาก ซึ่งพูดถึงหัวข้อนี้อย่างลึกซึ้งและเป็นระบบ
ฉันอยากถามว่าช่วงไหนกันแน่ที่การผสมผสานบางอย่างทำให้เห็น “รสนิยม” ของวิศวกรอย่างแท้จริง และอะไรคือ “ขอบเขตของรสนิยม” ที่แยกออกจาก technical trade-off สำหรับฉัน การตัดสินใจจำนวนมากมักถูกจัดเป็น “เป็น technical trade-off แต่พิสูจน์แบบเด็ดขาดไม่ได้ หรือความต่างเล็กน้อยจนแทบไม่สำคัญ” กล่าวคือ ถ้าเถียงกันยากก็ปล่อยให้เป็นเรื่องรสนิยมไป
ยังมีอีกประเด็นคือ โดยทั่วไปนักพัฒนาส่วนใหญ่มักไม่มีรสนิยมด้านแฟชั่น และเพราะอย่างนั้นจึงมักไม่เข้าใจ “รสนิยมที่ดี” โดยรวมมากนัก อีกทั้งสิ่งต่าง ๆ ในโลกเทคส่วนใหญ่ก็ไม่ได้ดูเท่หรือคูลเลยสำหรับคนนอกสายเทค ภาษาโปรแกรมไม่เท่ โลกนักพัฒนาเริ่มต้นจากจุดที่ “ไม่เท่” อยู่แล้วและมีแต่ลงไปอีก ตัวอย่างเช่น Rust, C++ ฯลฯ อยู่ในหมวด “ไม่เท่” ส่วนภาษาเชิงฟังก์ชันที่ไม่คุ้นเคย หรือ Bash, Linux ฯลฯ อยู่ในหมวด “ไม่เท่สุด ๆ”
รสนิยมที่ดีคือการเขียนโค้ดที่เรียบง่ายอย่างทรงพลัง จนดูเหมือนใคร ๆ ก็เขียนแบบนี้ได้
ขอแชร์อีกตัวอย่างหนึ่ง ตอนที่รื้อแล้วประกอบ Dodge Challenger รุ่นปี 72 ใหม่ ฉันทึ่งอยู่เสมอว่ารถคันนี้ถูกออกแบบมาได้เรียบง่าย ตรงไปตรงมา ราคาถูก แต่กลับทำงานได้ดีอย่างน่าทึ่ง ตัวอย่างเช่น ระบบไฟหน้าปัดต้องการ 5 โวลต์แยกจากแรงดันรวมของรถทั้งคัน (10~18V) จึงมีอุปกรณ์คล้าย buzzer ชนิดหนึ่งที่ใช้แม่เหล็กไฟฟ้า ทำหน้าที่ตัดวงจรเมื่อเกิน 5 โวลต์ และปิดวงจรเมื่อแรงดันต่ำกว่า ทำให้เกิดการ on/off อย่างรวดเร็วและได้ค่าเฉลี่ยออกมาเป็น 5 โวลต์ คนส่วนใหญ่มักเปลี่ยนมันเป็นตัวควบคุมแรงดันแบบอิเล็กทรอนิกส์ แต่พอทำแบบนั้นกลับพบว่าหน้าปัดไม่ทำงาน ที่จริงแล้วหน้าปัดเป็นกลไกเชิงกล จึงต้องอาศัยสัญญาณรบกวนเล็กน้อยในไฟ 5 โวลต์ ไม่เช่นนั้นเข็มจะค้างบ่อย กลายเป็นว่าไฟ 5 โวลต์แบบ “หยาบ ๆ” นี้กลับช่วยกันไม่ให้เข็มค้าง ถ้าจะเปลี่ยนเป็นแบบอิเล็กทรอนิกส์ ก็ต้องเติม ‘noise’ เข้าไปโดยตั้งใจ ฉันจึงประทับใจมากว่าอุปกรณ์กลไกง่าย ๆ แบบนี้ยอดเยี่ยมเพียงใด ทั้งในแง่ผลลัพธ์และความเรียบง่าย
คุณค่าที่แท้จริงของโค้ดเรียบง่ายแบบนี้ แม้จะช่วยลดภาระในการดูแลโค้ดหรือประหยัดเวลาคนทำงาน ก็มักไม่ได้รับการยอมรับอย่างเหมาะสม โค้ดที่ทำตามหลัก KISS(Keep It Simple, Stupid) กลับถูกดูแคลนบ่อยครั้งว่าไม่มีคุณค่าให้เห็น จนถึงขั้นมีทีม/องค์กรที่ทำหน้าที่เพียงจัดการความซับซ้อนที่ไม่จำเป็นจริง ๆ อยู่เลย
บางครั้งก็ดีที่วิศวกรทำสิ่งไม่ธรรมดาได้ แต่สิ่งที่สำคัญจริง ๆ คือวิศวกรที่แม้ตอนแรกจะดูยาก ท้ายที่สุดกลับค้นพบทางออกที่ธรรมดาและเรียบง่ายได้อยู่บ่อย ๆ
เวลาดูบัลเลต์ เรามักได้ยินแค่ว่า “ดูง่ายจัง!” แต่ความจริงคือพวกเขาซ้อมกันเป็นหมื่นครั้งจนทำให้มันดูง่ายจริง ๆ
ฉันเคารพคนที่สามารถสรุปสิ่งซับซ้อนให้เรียบง่ายได้อย่างแท้จริงมากที่สุดเสมอ แบบเดียวกับตัวอย่างใน K&R C ที่ชัดเจนคมกริบ เพียงแต่อยากให้มีคอมเมนต์ละเอียดขึ้นอีกหน่อย
คำถามว่า “ดูโค้ดแล้วเข้าใจได้ทันที และ onboard วิศวกรใหม่ได้ง่ายหรือไม่” นั้นไม่ได้ง่ายอย่างที่คิด เพราะคำว่าใหม่ไม่ชัดว่า หมายถึงคนประสบการณ์ 0 ปี 10 ปี หรือ 30 ปี เช่นกัน “ความอ่านง่าย” อาจดูเป็นแนวคิดชัดเจนสำหรับบางคน แต่ในความเป็นจริงมันเป็นสเปกตรัมตั้งแต่ 0 ถึงอนันต์ สมการของ Maxwell อาจชัดเจนมากสำหรับบางคน แต่ทึบแสงโดยสิ้นเชิงสำหรับอีกบางคน ดังนั้นฉันจึงสงสัยเสมอว่า เมื่อพูดว่า “โค้ดควรอ่านง่าย” นั้น เราหมายถึงให้อ่านง่ายสำหรับใครกันแน่
โค้ดที่อ่านง่ายหมายถึงโค้ดที่คำนึงถึงผู้อ่านและลดภาระทางการรับรู้ให้น้อยที่สุด นี่ก็เป็นเป้าหมายของ layered abstraction และ design pattern เช่นกัน แน่นอนว่ามันขึ้นอยู่กับความเชี่ยวชาญของผู้อ่านและความคุ้นเคยกับ codebase จึงเป็นเรื่องอัตวิสัย แต่จะปฏิเสธความอ่านง่ายไปเลยเพียงเพราะมันเป็นเรื่องอัตวิสัย ก็ดูเกินไปหน่อย เราคงพูดไม่ได้ว่า Joyce เรื่อง 'Ulysses' กับ Seuss เรื่อง 'The Cat in the Hat' อ่านง่ายพอ ๆ กัน
ฉันไม่เห็นด้วยกับคำกล่าวที่ว่า “ความอ่านง่ายไม่ใช่แนวคิดหนึ่ง” โค้ดที่ไม่มีใครอ่านออกคือโค้ดที่ทั้งผู้เขียนเอง (หรือ AI) และคนอื่นก็อ่านไม่ออก ส่วนโค้ดที่มีแต่ผู้เขียนอ่านออก ก็ยังไม่ถือว่าอ่านง่ายอยู่ดี
ในยุคของสมการ Maxwell มันยากจริง แต่รูปแบบที่เรารู้จักกันทุกวันนี้เป็นผลจากการที่ Heaviside และคนอื่น ๆ ขัดเกลาให้มีความอ่านง่ายมากขึ้น
ฉันคิดว่า “ความอ่านง่ายเฉพาะจุด” ของโค้ดบางส่วนไม่ค่อยมีความหมายเท่าไร หากมีการใช้แพตเทิร์นอย่างสม่ำเสมอทั่วทั้ง codebase ต่อให้แพตเทิร์นนั้นซับซ้อนขึ้นมานิดหน่อย โดยรวมก็ยังทำให้โค้ดอ่านง่ายได้อยู่ ความซับซ้อนชั่วคราวเป็นสิ่งที่ยอมรับได้ หากไม่กระทบคุณภาพโดยรวมของโค้ด
ความอ่านง่ายโดยมากมีเป้าหมายเพื่อลด ‘ความซับซ้อนโดยบังเอิญ(accidental complexity)’ ไม่ว่าจะเป็นสูตรแบบบทภาพยนตร์ อัลกอริทึมที่ซับซ้อน หรือสิ่งใดก็ตาม ถ้าสัญลักษณ์หรือรูปแบบการเขียนไม่ดี ก็จะเข้าใจได้ยากอยู่ดี สุดท้ายแล้ว สำหรับคำถามว่า ‘โค้ดควรอ่านง่ายสำหรับใคร’ คำตอบคือ ควรอ่านได้สำหรับวิศวกรที่เชี่ยวชาญในโดเมนนั้น รู้จักปัญหาอยู่แล้ว แต่ยังไม่เคยเห็นโค้ดชิ้นนั้นมาก่อน มันคล้ายงานวิจัยที่ควรอ่านง่ายสำหรับกลุ่มนักวิจัยในสาขานั้น สรุป No Silver Bullet
ฉันคิดว่าอุปมา “วิศวกรที่รสนิยมแย่ก็เหมือนเข็มทิศที่พัง ซึ่งสุดท้ายจะชี้ผิดทาง” อธิบายแก่นของเรื่องนี้ได้ดี คนประเภท ‘พังแบบคาดเดาได้’ พวกนี้คัดออกได้จากการสัมภาษณ์เสียด้วยซ้ำ ที่อันตรายกว่าคือคนประเภท ‘เข็มทิศพังบางส่วน’ ภายนอกดูเหมือนพอใช้ได้ แต่จริง ๆ แล้วมันเบี้ยวไป 127 องศาอย่างแม่นยำทุกครั้ง
บทความแนวนี้มักสับสนระหว่างสองประเด็น อย่างแรก มีการตัดสินใจที่แย่อย่างเป็นวัตถุวิสัยโดยไม่เกี่ยวกับรสนิยมหรือหลักการเลยจริง ๆ (เช่น ค้นหา O(n) ในลิสต์ เทียบกับค้นหา O(1) ด้วยดิกชันนารี) มีเรื่องที่เป็นเทคนิคและตัดสินแพ้ชนะได้ชัดเจนอยู่ อย่างที่สอง นอกนั้นล้วนเป็น trade-off ทั้งหมด จะใช้ map-reduce หรือลูปปกติก็แค่ชั่งเรื่องประสิทธิภาพ ความอ่านง่าย ความเข้ากันได้ ฯลฯ หากมีเหตุผลรองรับ ต่อให้ไม่ตรงกับความคิดฉันก็ไม่เป็นไร ปัญหาคือเมื่อคำตอบนั้นผิด หรือไม่ได้พิจารณา trade-off เลย ตรงนั้นจึงกลายเป็นเรื่องของการบำรุงรักษา และขึ้นอยู่กับบริบท เช่น ประสิทธิภาพหรือความถี่ในการใช้งาน ว่าควรไปแตะมันหรือไม่ ตราบใดที่ “เหตุผล(why)” ของการตัดสินใจนั้นชัดเจน ฉันก็ยอมรับได้ทั้งหมด แต่ก็ยังไม่แน่ใจว่านี่ควรเรียกว่า “รสนิยม” จริงหรือไม่
ปัญหาของบทความนี้คือมันพูดถึงประเด็นว่า “แต่ละคนให้คุณค่ากับสิ่งต่าง ๆ ไม่เหมือนกัน” แบบไร้บริบทเกินไป ในความเป็นจริง ถ้าเป็นวิศวกรก็ควรพอสัมผัสได้ว่าคุณค่าใดสำคัญที่สุดกับปัญหานั้น ๆ (=hard constraint) อิสระที่เหลืออยู่นอกเหนือจาก hard constraint นี้ต่างหากที่เหมาะจะเรียกว่า “รสนิยม” ถ้าเปรียบกับศิลปิน มันคือส่วนที่ยังเหลือให้กำหนดข้อจำกัดหรือเสรีภาพของตัวเองเพิ่มได้ นอกเหนือจากวัสดุและขนาดที่ถูกกำหนดไว้แล้ว รสนิยมที่ดีของวิศวกรซอฟต์แวร์จึงคล้ายกับการมุ่งสู่ ‘ความมินิมอลเชิงสุนทรียะ และการยับยั้งชั่งใจตนเองให้มากที่สุด’ สำหรับฉัน กรณีที่เรียกว่า “รสนิยมแย่” จริง ๆ คือการละเมิดหลักการโดยไม่มีเหตุผล กล่าวคือหลายครั้งมันคือการเข้าใจผิดว่า ‘ความคุ้นเคย’ คือ ‘ความเรียบง่าย’
หัวข้อ “คุณค่า” ในบทความนี้เชื่อมโยงได้กับคุณลักษณะของสถาปัตยกรรมซอฟต์แวร์ในวิทยานิพนธ์ปริญญาเอก ของ Roy Fielding วิทยานิพนธ์ของ Fielding เป็นที่รู้จักจาก REST ก็จริง แต่แท้จริงแล้วเป็นงานอภิปรายเรื่องสถาปัตยกรรมซอฟต์แวร์ที่กว้างและแข็งแรงกว่านั้นมาก มันช่วยให้เราคิดในกรอบของ “คุณลักษณะทางสถาปัตยกรรม” ต่าง ๆ (เช่น scalability, readability, maintainability ฯลฯ) และโดยส่วนตัวฉันอยากเน้นด้วยว่าการเข้าใจ ‘ข้อจำกัดทางสถาปัตยกรรม’ สำคัญมากเพียงใด
วิศวกรรมที่มีหลักการ(Principled engineering) ควรเป็นเรื่องพื้นฐานอยู่แล้ว บนพื้นฐานนั้นจะมีรสนิยมดีหรือแย่ก็ยังเป็นไปได้ แต่กลับกันไม่จริง ถ้าวิศวกรรมเองไม่ดี รสนิยมก็ไม่มีความหมาย รสนิยมที่แย่อาจบั่นทอนประสิทธิภาพของวิศวกรรมได้ แต่ไม่ได้ทำให้วิศวกรรมเป็นไปไม่ได้ในตัวมันเอง โดยพื้นฐานแล้ววิศวกรรมมีหน้าที่รองรับรสนิยม ตัวอย่างเช่น ต่อให้มีการออกแบบทางวิศวกรรมที่สมบูรณ์แบบแค่ไหน ถ้ามันเป็นสิ่งที่ไม่จำเป็นและไม่มีใครต้องการ ก็ไม่มีความหมายอยู่ดี
รสนิยมที่แย่สุดท้ายจะพาเราไปสู่สถานการณ์ไม่แน่นอน(X) ที่เราพยายามหลีกเลี่ยง สำหรับฉัน รสนิยมที่ดีคือการเตรียมฐานรากที่แข็งแรงและกลไกป้องกันไว้ใน codebase เพื่อรับมือกับความไม่แน่นอนของอนาคตที่กำลังจะมาถึง แบบนี้จึงจะไม่ตกอยู่ในความเสี่ยง
ดีมากจริงๆ
ต้นฉบับก็ดีอยู่แล้ว แต่เนื้อหาในคอมเมนต์ก็ดีมากจริง ๆ เช่นกัน
พอนึกถึงเรื่องรสนิยม ก็จะนึกถึงวิดีโอ TED ของ Torvalds ขึ้นมาครับ:
https://www.ted.com/talks/linus_torvalds_the_mind_behind_linux
ตั้งแต่นาที 14:20 เป็นต้นไป ว่าด้วยรสนิยมที่ดีซึ่งมองได้จากวิธีการ implement โค้ดลบ entry ของ linked list
แม้แต่สิ่งที่ถูกพูดถึงในความเห็นบน Hacker News ว่าเป็น “การตัดสินใจที่แย่อย่างเป็นภววิสัย (เช่น ค้นหาแบบ O(n) ในลิสต์ vs ค้นหาแบบ O(1) ด้วยดิกชันนารี)” ก็อาจต้องตัดสินต่างออกไปตามบริบท
เพราะถ้ามีการค้นหาเพียงครั้งเดียว ต้นทุนในการสร้างแฮชเทเบิลอาจสูงกว่าการค้นหาแบบ O(n) ในลิสต์ก็ได้
เป็นความเห็นที่ดีนะครับ