Continuous Integration – เทคนิคการพัฒนาโปรแกรมแบบบูรณาการต่อเนื่อง

เข้าเรื่องดีกว่า Continuous Integration หรือการทำบูรณาการอย่างต่อเนื่อง … อ่านชื่อไทยคงจะงง เอาเป็นว่าผมขอเรียกย่อ ๆ ว่า CI ละกัน CI เป็นวิธีปฎิบัติในการพัฒนาซอฟต์แวร์อย่างหนึ่งที่เน้นให้นักพัฒนารวมเอาโค๊ดของตัวเองเข้ามาในโค๊ดสายหลักอย่างต่อเนื่อง และนักพัฒนาแต่ละคนจะทำงานอยู่บนฐานโค๊ด (Code Base) เดียวกัน ทำให้มีความแตกต่างระหว่างกันน้อยที่สุด

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

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

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

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

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

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

การรวมโค๊ดบ่อย ๆ แต่เป็นชุดเล็ก ๆ นั้นมองเผิน ๆ อาจจะเป็นภาระของโปรแกรมเมอร์เพราะต้องทำบ่อย  แต่ว่าโปรแกรม version control นั้นมีความสามารถในการรวมโค๊ดด้วยตัวมันเองอยู่แล้วในระดับหนึ่ง ดังนั้นเอาเข้าจริง ๆ มันมีผลกระทบต่อตัวโปรแกรมเมอร์น้อยมาก

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

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

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

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

พอถึงจุดที่ Unit Test จบแล้ว ถ้าใช้วิธี Agile ควบคู่ด้วยขั้นตอนต่อไปก็คงเป็นการส่งตัวโปรแกรมไปให้ QA ทดสอบต่อในขั้นต่อไป (Functional Testing) นะครับ ซึ่งจะไม่พูดถึง

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

เขียนเองแล้วก็อยากทำ แต่ว่าด้วยลักษณะของงานตัวเองคงไม่มีโอกาสล่ะครับ แฮะ ๆ

มาเขียนบล็อกกันเถอะ

วันนี้อยากจะมาชวนให้เขียนบล็อกกันครับ

บล็อกคืออะไร ? บล็อก หรือภาษาอังกฤษว่า Blog นั้นเป็นพื้นที่ที่เจ้าของนำเอาเนื้อหามาเขียนเอาไว้โดยมักจะเรียงตามวันเวลาที่มีการบันทึก คล้าย ๆ กับไดอารี่ครับ เพียงแต่ว่ามันกว้างกว่าตรงที่เนื้อหาที่เขียนนั้นจะเป็นอะไรก็ได้ อาจจะเป็นบันทึกประจำวันเหมือนไดอารี่ หรือเป็นเนื้อหาที่ผู้เขียนสนใจ

อย่างบล็อกของผมนั้นจะเป็นกรณีหลัง ผมจะเขียนเฉพาะเรื่องที่สนใจ และไม่เขียนทุกวันครับ

ที่มาของคำว่า Blog นั้น คือ Web Log โดยเป็นการเอาตัวอักษรตัว B ที่เป็นตัวท้ายของคำหน้ามาเชื่อมกับคำว่า Log ที่อยู่ข้างหลัง ซึ่ง ในอดีตนั้นบล็อกเป็นการเขียน log เรื่องราวที่เกิดขึ้นบนเว็บ โดยผู้ดูแลเว็บ (หรือที่เรียกว่าเว็บมาสเตอร์) เช่น ระบบล่มบ้าง อัพเกรดสคริปท์ใหม่บ้าง หรือแจ้งแบนสมาชิกบ้าง เป็นต้น แต่ก็มีเรื่องที่ไม่เกี่ยวข้องกับเว็บมาเขียนลงไปในบล็อกบ้างเหมือนกัน ภายหลังก็มีคนเอาไอเดียนี้ไปสร้างเป็นระบบที่เป็นตัวเว็บที่แยกออกจากเว็บหลักอย่างเป็นเอกเทศ เพื่อที่จะเอาไว้เขียนเนื้อหาอะไรก็ได้อย่างที่พูดถึงข้างบน แต่ก็ยังคงเรียกว่าบล็อกอยู่มาจนถึงทุกวันนี้

ทีนี้เขียนบล็อกแล้วได้อะไร ?

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

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

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

การเขียนบล็อกนั้นให้อะไรมากกว่าที่คิดครับ ดังนั้น มาเขียนบล็อกกันเถอะ

เปรียบการเขียนโปรแกรมเหมือนการประพันธ์ดนตรี

วันนี้ขอขึ้นด้วยเพลง “ใครนิยาม” ที่ Cover โดยคุณชายพุฒิพัชร … เอ๊ย คุณพัชรแห่ง iHearBand ละกันนะครับ ที่ยกคุณพัชรขึ้นมาเพราะว่าจะได้เห็นว่าในวงการไอทีบ้านเราก็มีนักดนตรีเก่ง ๆ หลายท่าน คุณพัชรก็ถือเป็นตัวอย่างที่ดีทีเดียว (ผมไม่เคยได้มีโอกาสได้พูดคุยส่วนตัว แต่เคยได้ชมฝีมือสด ๆ ในงานแต่งพี่ที่ทำงานครั้งหนึ่งครับ)

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

ถ้าให้ยกตัวอย่าง หลาย ๆ คนคงเคยใช้ระบบภาษาไทยบน Windows มาแล้ว แต่คงมีน้อยคนที่รู้ว่าระบบภาษาไทยบน Windows 95 และบน Office 95 นั้นมีทีมงานคนไทยคนหนึ่งที่เป็นนักดนตรีมาก่อน ซึ่งก็คือคุณป้อ นุสรณ์ พจน์พิพัฒน์ หรือบางคนอาจจะเคยเจอพี่เขาในชื่อคุณ McDuck (ถ้าผมจำไอดีเขาไม่ผิดนะ :)) พี่ป้อเคยเป็นสมาชิกของวงดิโอฬารโปรเจคมาก่อนครับ ก่อนจะไปรับงานไมโครซอฟท์พัฒนาระบบภาษาไทยอย่างที่ว่ามาข้างต้นนั่นล่ะ หลังจากนั้นก็เปิดบริษัทพัฒนาระบบภาษาไทยของ Windows CE (ปัจจุบันถูกแทนที่ด้วย Windows Embeded และ Windows Phone) และปลาดาวออฟฟิศ 

กลับมาเรื่องของเรากันต่อหลังจากที่ยังไม่เข้าเรื่องซะที สำหรับผม การเขียนโปรแกรม ก็เหมือนกับการเขียนสกอร์โน๊ต ก็คือเราใส่สัญลักษณ์ที่คนอ่านรู้เรื่องบ้างไม่รู้เรื่องบ้างลงไปในสื่อบันทึกบางอย่าง เพื่อให้คน/สัตว์/สิ่งของมาอ่านสื่อบันทึกนั้นแล้วทำตามที่เราต้องการ 

ใช่ครับ ทั้งโค๊ดโปรแกรม และแผ่นสกอร์โน๊ต มันก็คือ “บันทึกคำสั่ง” นั่นเอง

ผมเคยถามคนที่เรียนดนตรี เขาก็บอกว่า สิ่งที่เขาต้องเรียนนอกจากการเล่นเครื่องดนตรีแล้ว ยังต้องศึกษาเรื่องการอ่านโน๊ต และทฤษฎีดนตรีพื้นฐานต่าง ๆ ก่อนที่จะได้มาเรียนเรื่องประพันธ์ดนตรี

การเขียนโปรแกรมก็เหมือนกัน เราก็ต้องรู้ก่อนว่าโปรแกรมมันทำงานยังไง จากนั้นก็เริ่มหัดเขียนโปรแกรม ซึ่งก็เป็นการเรียนรู้เรื่องสัญลักษณ์ต่าง ๆ ที่ใช้ในการเขียนโปรแกรมนั่นเอง และจากนั้นก็เริ่มเรียนทฤษฎีต่าง ๆ ที่เกี่ยวข้อง

พอถึงจุดนี้เราก็เอาความรู้ที่ได้ต่าง ๆ มาเรียงร้อยเข้าด้วยกัน สร้างเป็นผลงานขึ้นมา ผ่านทางคีย์บอร์ดและเมาส์ โดยใช้คนละโปรแกรมกัน อย่างถ้าเราจะเขียนสกอร์ก็ใช้ Sibelius ส่วนถ้าจะเขียนโปรแกรมก็ใช้ Visual Studio จากนั้นก็เอาผลลัพท์ที่ได้ไปสั่งให้คน/สัตว์/สิ่งของทำตามคำสั่งที่บันทึกอยู่ก็เท่านั้นเอง

ที่จริงทั้งการเขียนโปรแกรมและเขียนโน๊ตก็ใช้ปากกากับกระดาษก็ได้เหมือนกันแหละ แต่ว่าตอนนี้มันศตวรรษที่ 21 แล้วใช่ไหมครับ 😉

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

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

ก็เหมือนกัน ใช่ไหมครับ

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

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

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

ดังนั้นผมว่าถ้าเราสามารถเอาแนวความคิดพื้นฐานของศาสตร์หนึ่งมาปรับคิดใช้ประโยชน์กับศาสตร์อีกแขนงนึงได้มันก็สนุกดีนะ