Thursday, September 29, 2011

Grails คืออะไรหรา

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

ข้อดีของ Grails ที่สัมผัสได้
สำหรับบางคนการพัฒนา Web Application ซักตัวหนึ่งถือเป็นเรื่องค่อนข้างซับซ้อน แม้ว่า Project ที่เราต้องการจะพัฒนานั้นจะเป็นระบบที่ง่ายขนาดไหน ยกตัวอย่างเช่น

  1. รับ HTTPRequest
  2. แปลงเป็นชนิดข้อมูลไม่ว่าจะเป็น Object หรือ Primitive
  3. ตรวจสอบข้อมูลทั้งในเชิง Value Validation และ Type Validation
  4. ทำการบันทึกค่าลง Database

ซึ่งในการแสดงข้อมูลก็จะต้องทำหลายกระบวนการอีกเช่นกัน ซึ่งขั้นตอนเหล่านี้เกิดขึ้นซ้ำแล้วซ้ำเล่าอย่างหลีกเลี่ยงไม่ได้ (นี่ขนาดพูดถึงแค่ฝั่ง Server นะเนี่ย ยังไม่รวมถึง พวก AJAX หรือ RIA) โดยตลอดหลายปีที่ผ่านมาก็มี Framework มากมายหลายหลากผุดขึ้นมายังกะดอกเห็ด เพื่อช่วยให้เราลดขึ้นตอนที่ยุ่งยากในการพัฒนา Web Application ที่กล่าวมาข้างต้น แต่ก็ต้องแลกกับการมี Configuration Files เพิ่มขึ้นมาอยู่ใน Project เช่น Struts, Spring, Hibernate (เพราะนี่คือพื้นฐานของการสร้าง Framework) และแน่นอนไม่มี Framework ไหนจะสามารถตอบโจทย์ของนักพัฒนาทั้งน้อยใหญ่ได้ทั้งหมด บางงานอาจจะต้องใช้ Framework หลายตัวมาใช้งานร่วมกัน (Integrate) แต่การทำเช่นนั้นก็จะทำให้เกิด Configuration Files มากมาย ตัวอย่างนึงที่ดีในการทำให้เห็นภาพปัญหานี้ก็คือ สมมุติว่าเราจะเพิ่มหน้าจอหนึ่ง เราจำเป็นจะต้องเข้าไป Config ในไฟล์หลายตัว (อย่างน้อยก็ struts-config.xml)  แล้วถ้าใน Project นี้ใช้ Hibernate ด้วยล่ะ (Config กระจาย)
จากปัญหาเหล่านี้ Grails ช่วยท่านได้ครับ ลองดูประโยชน์ของ Grails ดังนี้

1. ลดจำนวน Configuration Files
เอาละเว้ย แค่อันแรกก็โดนใจกระผมอย่างแรงครับ เนื่องจาก Grails ใช้แนวคิด Convention Based ทำให้ลดจำนวน Configuration ไปได้มากโข แม้หลายคนจะบอกว่า "เมิงก็ให้ IDE Generate ให้สิ เดี๋ยวนี้มีเป็น Wizard เลยนะเออ" แต่ความจริงแล้ว IDE มันก็แค่พรางปัญหาเหล่านี้ให้เท่านั้นแหละ เพราะความซับซ้อนของมันก็ยังคงเดิม
ซึ่งสำหรับ Grails แล้วมองว่าหากสร้าง Class นึงขึ้นมา (ตามแบบแผนนะ) Class อื่นที่เกี่ยวข้อจะถูก Generate ขึ้นมาโดยมีชื่อ File, Path ที่เป็นระบบขึ้นมาอัตโนมัติ (โอ้โห) ยกตัวอย่าง


 หากเราสร้าง User.groovy ขึ้นมามันก็จะ Generated Configuration File (ซึ่งมีไม่กี่ FIles) แล้วก็ Controller ให้เองภายใต้ Package ที่เหมือนกันเป๊ะ (จอร์จมาก) แต่ทั้งนี้ทั้งนั้น หากไม่ชอบที่ Grails มัน Generate มาให้ก็สามารถเข้าไปเปลี่ยนแปลงได้ตลอดเวลา

2. ไม่ต้อง Redeployed แถมเขียนไม่กี่บรรทัดด้วยนะเออ
อันนี้ก็แจ่มแมวอีก Feature เนื่องจากการพัฒนาด้วย Java ในการ Run แต่ละครั้งอาจจะต้อง Redeploy และ Restart Server ซึ่งบางทีค่อนข้างเสียเวลา แต่เนื่องจาก Grails สามารถ Dynamic Language ได้ซึ่งจะทำให้เราพัฒนา Java ร่วมกับ Groovy ซึ่งมีลักษณะเป็นภาษา Script (ไม่ต้อง Redeploy) ได้ แถมข้อดีของ Groovy ยังมีอีกก็คือ เขียนนิดเดียว ได้ผลเท่า Java (นี่แหละที่เจ็บปวด T^T)

หลังจากการเล่นมาครึ่งวันเจอแค่นี้ คิดว่าอีกไม่นานก็คงจะเจออะไรมากมายที่เป็นประโยชน์ต่อการทำงาน เอาไว้มาแชร์ใหม่นะจ๊ะ ฟริ๊ววววววว!!

Thursday, September 1, 2011

Test Driven Development ภาคแนะนำ

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

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

     Test Driven Development (TTD) คือขั้นตอนในการพัฒนาซอฟท์แวร์วิธีหนึ่ง ซึ่งสามารถเพิ่มผลผลิต (Productivity) ของเหล่า Coder ทั้งหลายได้ โดยหากนำไปใช้อย่างชำนาญพอแล้วยังทำให้ลด Defects ได้เยอะเลยทีเดียว

     โดยวิธีการของ TTD นั้นแสนจะง่าย (จริงป่าววะ) มันคือการกลับหัว Software Development Process แบบเดิมที่แสนจะน่าเบื่อจาก Design - Code - Test เป็น Test - Code - Refactor อันแสนสนุกและท้าทายแทน ซึ่งใครจะเชื่อว่าไอ้การ "สลับตำแหน่ง" แค่เนี้ยมันจะช่วยให้เราสร้างซอฟท์แวร์ที่มีคุณภาพได้อย่างไม่น่าเชื่อ ถึงแม้ว่า Requirement จะมีการเปลี่ยนแปลง ทำให้เป็นที่ปวดเศียรเวียนเกล้าอยู่ตลอดเวลา สิ่งนี้จะช่วยให้เราไม่หลงประเด็นจากสิ่งที่ลูกค้าต้องการ โดยที่ค่าใช้จ่ายในการ Maintain หรือแก้ Defects ก็ต่ำกว่าด้วยเพราะมีกระบวนการตรวจสอบความถูกต้องที่ดีกว่า (Automate Test Suite) และเหนือสิ่งอื่นใดในการทำงาน Coder ทั้งน้อยใหญ่จะทำงานไปด้วยความ (เมา) มันส์ เนื่องจากรูปแบบการเขียนจะเต็มไปด้วยความท้าทาย เหมือนเล่นเกมส์และมีเป้าหมายที่แน่นอน (ว่ากุจะต้องเขียนแล้วให้ได้ผลแบบนี้นะ) โดยในบล๊อกนี้จะไม่กล่าวถึงโพรเซสปกติ เนื่องจากสามารถหาได้ทั่วไป ไม่อยากเขียนซ้ำกับคนอื่นให้รกพื้นที่อินเตอร์เนท หากแต่จะกล่าวแนะนำและชี้ให้เห็นความแตกต่างในแง่มุมของ Test และการแปลงจาก Requirement สู่ Test Case แทน เนื่องจากถ้าเอาทั้งโพรเซสมันเยอะ กุขี้เกียจครับ

     เนื่องจากกระบวนการแรกของการทำ TDD นั้นคือการสร้างกระบวนการทดสอบพฤติกรรมของระบบก่อน แต่ทั้งนี้ทั้งนั้นการรู้เรื่อง Requirement อย่างละเอียดจะนำไปสู่การคิด Test Fail ดังกล่าวได้อย่างสมบูรณ์ยิ่งขึ้น
  1. เหนือสิ่งอื่นใดเราต้องทำการวิเคราะห์ Requirement ซะก่อน ซึ่งโดยปกติแล้ว SA หรือผู้ที่ได้รับมอบหมายให้ Design System จะทำการแตก Requirement เป็น Task ย่อย ซึ่ง "อาจจะ" สร้างปัญหาให้กับ Coder หาก Task นั้นถูกเขียนไม่ละเอียดพอ ดีไม่ดีก็เป็นที่ตัว Coder ซะเองที่อ่านไม่เข้าใจ เนื่องจากรูปแบบของ Task นั้นไม่ค่อยมีความเชื่อมโยงกับตัวระบบในรูปแบบที่จับต้องได้เท่าที่ควร สังเกตุได้จาก Task บางข้อเมื่อ Coder เขียนเสร็จ แต่ไม่รู้จะ Test ยังไง หรือ ไม่สามารถตรวจความก้าวหน้าของงานตัวเองได้อย่างชัดเจน เนื่องจาก
    1. Task แค่บอกว่าเราควรทำอย่างไร แต่ไม่ได้บอกว่า เมื่อทำเสร็จแล้วงานควรจะออกมาเป็นอย่างไร 
  2. ดังนั้นสิ่งที่ TDD พยายามจะบอกคือ พวกเมิงแตก Requirement เป็น Test แทนเถอะครับ ตอนแรกอาจจะขัดในการเปลี่ยนมุมมอง แต่เดี๋ยวก็จะเจ็บและชินไปเอง โดย Test ที่ดีนั้นจะต้องมีคุณสมบัติ  คือ เล็ก และ มีจุดประสงค์ในการทดสอบที่ชัดเจน
  3. ให้ลองนึกภาพ Test เป็นเหมือน Blackbox หรือ เครื่องจักรโดเรม่อนอะไรซักอย่าง ที่ไม่ซับซ้อนคิดแค่ว่าใส่ Input แบบนี้ไป ควรจะได้ Output แบบไหนออกมา
โดยสิ่งเหล่านี้ (TDD) จะส่งผลให้เราสามารถแก้ปัญหาด้านบนได้ ไม่มากก็น้อย ซึ่งอันที่จริงแล้วในแง่การนำไปใช้จริง ผมยังไม่เคยผ่านองค์การที่นำมาใช้อย่างเต็มรูปแบบซักเท่าไหร่ จึงอาจจะยังไม่ค่อยเห็นภาพในบางมุม ถ้าใครมีคำแนะนำ หรือมีมุมมองอยากจะแบ่ง ก็เต็มที่เลยครับ