สุดท้ายมันก็ขึ้นอยู่กับหน้าที่ และการแก้สถานการณ์เฉพาะหน้า

เมื่อเดือนที่แล้วผมมีรับการติดต่อให้ไปเล่นโฆษณาให้กับโรงเรียนสอนดนตรีแห่งหนึ่ง ด้วยเหตุที่ว่าทางเขาได้อ่านบล็อก เล่นให้เหมือนหรือเล่นให้ต่าง แล้วชอบก็เลยอยากเอาคอนเทนท์ตรงนั้นไปถ่ายทอดต่อ ซึ่งก็เป็นเรื่องน่ายินดีสำหรับผมว่ามีคนอ่านบล็อกผมด้วย (ฮา) สำหรับเรื่องราววันนี้จะเป็นเรื่องที่จะบอกว่าเป็นตอนต่อกับบล็อกอันนั้นก็ได้ครับ

คืออย่างที่ผมเคยเล่าให้ฟังนั่นแหละว่า การเล่นดนตรีมันไม่จำเป็นต้องเล่นให้เหมือนเป๊ะ และการยึดติดกับต้นฉบับมากเกินไปกลับทำให้วงล่มได้ ตอนนั้นผมยกตัวอย่างมือกลองที่ไม่นับเข้าเพลงให้ฟังไปแล้วทำให้วงไม่สามารถขึ้นเพลงได้พร้อม ๆ กัน

แต่ว่า … ถ้าเราไม่เล่นตามต้นฉบับแล้ว เราจะเล่นยังไงล่ะ ??

การที่เราจะตอบคำถามนี้ได้นั้น ผมมองว่ามันมีสองประเด็นหลัก ๆ คือ หน้าที่ และสถานการณ์ กล่าวคือเวลาเล่นดนตรีกันเป็นวง หลาย ๆ คนมักจะคิดว่ามันคือการเล่นตามโน๊ต เมื่อทุกคนเล่นได้เป๊ะมันก็จะเข้ากันได้เองราวกับปาฎิหารย์ ในความเป็นจริงไม่ใช่ทุกสถานการณ์ที่สามารถทำแบบนั้นได้

ขอยกตัวอย่างเพลงนึง หลาย ๆ คนน่าจะรู้จักเพลง Hotel California ใช่ไหมครับ ? Don Felder ที่เป็นผู้แต่งทำนองและเรียบเรียงเพลงนี้เคยกล่าวเอาไว้ว่า ในเวอร์ชันสตูดิโอ เพลงนี้ใช้กีตาร์มากถึง 12 ไลน์ … ถ้าเราจะเล่นให้เหมือนเป๊ะ ๆ จะต้องใช้มือกีตาร์ถึงสิบสองคนเล่นพร้อม ๆ กัน ซึ่งนั่นเป็นไปไม่ได้ (ในเวอร์ชันสตูดิโอ Don เป็นคนที่อัดกีตาร์ทุกไลน์ รวมทั้งโซโล่ประสานบรรลือโลกนั่นด้วย) แม้แต่กับวง The Eagles เองก็ไม่สามารถทำได้ เพราะมีมีมือกีตาร์เพียงแค่ 3 คนเท่านั้น ในสถานการณ์เช่นนี้เพลงจำเป็นจะต้องเรียบเรียงใหม่ทั้งหมด เพราะถ้าเล่นให้เหมือน ก็จะเล่นได้แค่ 3 ไลน์เท่านั้นเอง

สิ่งที่ The Eagles ทำก็ไม่ได้ยากอะไรครับ เขาก็ ใช้กีตาร์โปร่งยืนพื้นหนึ่งตัว (Glenn Frey เป็นคนเล่น) และไลน์ที่เหลือก็คัดเอาแต่ไลน์ fill-in เล่นโดย Don และ Joe Walsh เท่านั้น (ถ้าสังเกตคือเพลงนี้ Don ต้องใช้กีตาร์ไฟฟ้าสองคอเล่น คอ 12 สายเล่นตอนอินโทร อีกคอหนึ่งเล่นที่เหลือ เพราะว่าไลน์หลังจากนั้นกีตาร์ 12 สายมันก็ไม่ได้จำเป็นสักเท่าไหร่)

นี่คือการปรับเพลงให้เข้ากับสถานการณ์ ถ้าเกิดว่าในวงมีมือกีตาร์มากกว่า 3 คน ก็อาจจะเล่นอีกแบบหนึ่ง หรือถ้ามีน้อยกว่า ก็เล่นอีกแบบหนึ่งก็ได้ (อาจจะตัด fill-in ประสาน หรือใช้ harmonizer แทน)

แต่ การปรับให้เข้ากับสถานการณ์นั้น สิ่งที่สำคัญก็คือการรู้ว่าหน้าที่ของผู้เล่นแต่ละคนคืออะไร และคอยช่วยเหลือกันให้เพลงมันฟังดูออกมาสมบูรณ์ครับ มันเป็นสิ่งที่ต้องตกลงกันก่อนว่าใครจะมีหน้าที่อะไร มือกลองมีหน้าที่นับเข้าเพลง เพื่อให้ทุกคนรู้ว่าความเร็วของเพลงเป็นแบบไหน มือเบสมีหน้าที่คอยอุ้มเสียง ทำให้เพลงฟังดูเต็ม และมีหน้าที่สร้าง groove ให้ผู้เล่นคนอื่นเล่นตาม มือกีตาร์กับมือคีย์บอร์ดสร้างเสียง harmony ขึ้นมาอีกชั้น เพื่ออุ้มนักร้องขึ้นมา มือกีตาร์อีกคนคอยปิดช่องว่างภายในเพลง อะไรลักษณะนี้

ซึ่งจริง ๆ มันก็มีไกด์ไลน์คร่าว ๆ นั่นแหละ ว่าใครจะเล่นอะไรแบบไหน หรือแม้กระทั่งสลับหน้าที่กันเลยก็ยังได้ ขึ้นอยู่กับสถานการณ์ในตอนนั้น ซึ่งพอพูดถึงสถานการณ์เฉพาะหน้าแล้ว สิ่งที่สำคัญที่สุดสำหรับนักดนตรีก็คือ “การฟัง” นั่นแหละ ผู้เล่นจะต้องคอยฟังเสียงที่คนอื่นในวงเล่นอยู่ตลอดเวลา และคอยหาที่อยู่ของตัวเองในตอนนั้น พยายามทำหน้าที่ให้ดีที่สุด

แล้วก็ บางครั้งเราเล่นเพลงยาก ทักษะเราไม่ถึง เราก็สามารถที่จะปรับเปลี่ยนให้เข้ากับความสามารถของเราได้เช่นกัน หรือถ้าคีย์สูงเกินไป นักร้องร้องไม่ได้ ก็สามารถปรับลงมาให้นักร้องสามารถร้องได้ด้วยเหมือนกันครับ ตรงนี้ก็เป็นหนึ่งในสถานการณ์เฉพาะหน้าด้วย มันไม่ได้จำเป็นเลยว่าจะต้องเล่นให้ยากเหมือนต้นฉบับ

หรือบางงาน นักร้องอาจจะอยากเด่นนิดนึง (พวกงานประกวด) ในท่อนโซโล่ระหว่างที่เขา adlib อยู่ นักดนตรีก็ไม่ต้องโซโล่ก็ได้ ปล่อยนักร้องเขาเด่นของเขาไปก็อาจจะดีกว่า อะไรแบบนี้

สุดท้ายแล้ว สิ่งที่สำคัญที่สุดคือ เล่นยังไงให้โดยรวมมันฟังดูดีเท่านั้นเอง

ตรงนี้จริง ๆ ไม่ใช่แค่ดนตรีครับ กับอะไรก็แล้วแต่ ผลลัพท์สำคัญที่สุด คนทำงานก็แค่ต้องมีทักษะที่จะรับรู้สถานการณ์โดยรวม รู้ว่าหน้าที่ของตัวเองคืออะไร และจะทำอย่างไรเพื่อแก้ไขสถานการณ์เฉพาะหน้าให้ได้เท่านั้นเอง

เขียนโค๊ดมาเป็นสิบ ๆ ปี วันนี้มีคนมาบอกว่า “ยูต้องเขียน Unit Test นะ”

เกริ่นนิดคือ Unit Testing เนี่ยมันเริ่มแพร่หลายประมาณช่วงต้น 2000 ครับ ดังนั้นถ้าเป็นโปรแกรมที่เขียนมาเป็นสิบ ๆ ปี จะไปถามหา Unit Test แล้วดันมีขึ้นมาเนี่ย เรียกว่าปาฎิหารย์เลยก็ยังได้

Unit Testing อย่างที่เคยพูดถึงหลาย ๆ ครั้ง มันคือการทดสอบโค๊ดที่ระดับหน่วยย่อย ก็คือที่ระดับฟังก์ชันและระดับคลาส โปรแกรมเก่า ๆ มักจะไม่มีเพราะมักจะเป็นการทดสอบด้วยมือ และการใช้มือเรียกใช้ฟังก์มันก็ออกจะลำบากนิดนึง (ทำได้แต่อัตราการปนเปื้อนสูง) และทั้งตัวนักพัฒนาและผู้บริหารเองจะไม่ค่อยเห็นความสำคัญเท่าไหร่ ก็เพราะมันเป็นโปรแกรมที่เอาไปคิดเงินลูกค้าไม่ได้นั่นเอง แต่ในระยะยาวมันสำคัญมาก ๆ เพราะมันเป็นการแสดงความชัดเจนของโปรแกรม (ว่าหน่วยโค๊ดนั้น ๆ ทำอะไร ผลลัพท์ที่ได้ควรเป็นอย่างไร และอินพุตชุดไหนที่รองรับแน่นอน) และความน่าเชื่อถือของโปรแกรม (โปรแกรมที่ทดสอบบ่อยจะมีอัตราการเกิดปัญหาต่ำกว่า)

ทีนี้จะเขียน Unit Test ได้ดีได้นั้น ส่วนสำคัญอย่างหนึ่งคือตัวหน่วยโค๊ดเอง ก็คือตัวโปรแกรมจะต้องออกแบบมาให้ทดสอบได้ง่าย มีการแบ่งสัดส่วนที่ชัดเจน แต่ละโปรซีเยอร์จะทำงานแค่อย่างเดียว โปรแกรมลักษณะนี้จะออกแบบ Unit Test ได้ง่ายและมีประสิทธิภาพ ในทางกลับกันถ้าเป็นโค๊ดที่เขียนมาไม่ดีนั้น การทดสอบจะทำได้ยากมาก ๆ

นึกสภาพ … ฟังก์ชันเดียว แต่คืนค่าผลลัทพ์ออกมาสองร้อยกว่าชิ้นโดยที่ไม่มีความเกี่ยวข้องกันเลยดูนะครับ … การเขียน Unit Test กับฟังก์ชันแบบนี้นี่ฝันร้ายเลยนะ (ฟังก์ชันแบบนี้มีจริง ๆ ครับ)

ผมเคยเล่าให้ฟังในส่วนของ Legacy Code ว่า Legacy Code ก็คือโค๊ดที่ไม่มี Unit Test กำกับ (เป็นโค๊ดที่ไม่เป็นที่ต้องการ) และเคยเขียนไว้อีกว่า การจะสร้าง Unit Test ได้นั้นจำเป็นจะต้องมีการ Refactor โปรแกรมด้วย ไม่เช่นนั้นต่อให้เขียนออกมาได้ Unit Test ก็ไม่ครอบคลุมครับ นึกสภาพฟังก์ชันข้างบนไว้แล้วคิดเล่น ๆ ว่าแล้วจะทดสอบยังไงดูก็ได้ครับ

ทีนี้ปัญหาของ Legacy Code อีกอย่างคือ สมมติว่าถ้าเราประกาศว่า “เอ้า มาทำ Unit Test กันเถอะ” ปฎิกิริยาแรกที่จะเจอคือ “ภาระฉันเพิ่ม ทำไมต้องทำด้วย” โดยเฉพาะอย่างยิ่งถ้าเป็นคนที่ไม่ได้เขียนโค๊ดใหม่ แต่เป็นการแก้ไฟล์เก่า บางทีเราเพิ่มแค่บรรทัดเดียว แต่ต้องเขียน Unit Test ให้ครอบคลุมกับทั้งโปรซีเยอร์ … คือ ร้องโอ้พระสงฆ์กันเลยล่ะครับ

คือต้องเข้าใจก่อนว่า คนสมัยก่อน เขาแก้โค๊ด เขาก็จะทดสอบกับเฉพาะปัญหาที่เขาแก้ เขาไม่เสียเวลามาดูปัญหาที่เขาไม่ได้ถูกสั่งให้แก้ไงครับ

แต่ในระยะยาว ไอ้เทสต์ที่เขาเขียนมันจะมาช่วยยืนยันว่า โค๊ดที่เราแก้ไปมันไม่ไปกระทบส่วนที่เราไม่ได้แก้น่ะครับ การมี Unit Test มันถึงเป็นเรื่องดีไง

คือผมคิดว่า Unit Test มันจะเป็นประโยชน์ในระยะยาว แต่ถ้าเราบอกว่าให้คนมาเขียน Unit Test แบบ “เฮ้ย ถ้ายูแก้ไฟล์นี้ ยูเขียน Unit Test ให้ด้วยนะ” แบบนี้มันก็ดูจะไม่เป็นธรรมกับคนเขียนโค๊ดเท่าไหร่ ผมคิดว่าทางที่ดีควรจะทำเป็นโครงการ กำหนดทิศทางและขอบเชตให้แน่นอน และค่อย ๆ เพิ่ม Unit Test เข้าไป พร้อมกับ Refactor โค๊ดให้อยู่ในสภาพที่ทดสอบได้ดีด้วย ไม่ใช่แค่ว่าเราจะยัด Unit Test เข้าไปในโปรแกรมเดิมแล้วมันจะใช้งานได้ครับ …