Grails:Introduction
From Blognone
Contents |
เกรลคืออะไร
เกรลส์ (Grails) เป็นเฟรมเวิร์คสำหรับพัฒนาเวบแอพพลิเคชั่นและแอพพลิเคชั่นระดับเอ็นเตอร์ไพรส์ที่ออกแบบมาเพื่อให้ง่ายทั้งในแง่ของการพัฒนาและการดูแลรักษา ในปัจจุบันเกรลส์ได้ออกมาถึงรุ่น 1.1 และกลายเป็นเฟรมเวิร์คที่ได้รับความสนใจในพัฒนาแอพพลิเคชั่นเพื่อทำงานบนจาวาแพล็ตฟอร์ม
ในด้านเทคนิคแล้ว เกรลส์คือแอพพลิเคชันเฟรมเวิร์คที่ใช้ภาษากรูวี่ (Groovy) และทำงานบน Java Virtual Machine (JVM) โดย เกรลส์ช่วยลดความซับซ้อนในการพัฒนาโดยได้รับอิทธิพลจากรูบี้ออนเรลส์ (Ruby on Rails - RoR) คือ ใช้แนวคิด "convention over configuration" หรือ "ข้อตกลงแทนการปรับแต่ง" จุดแข็งของเกรลส์ที่ต่างจาก RoR ก็คือ เกรลส์ใช้คอมโพเนนท์และไลบรารีฝั่งเซิร์ฟเวอร์ของจาวาที่ได้รับการพิสูจน์ในการใช้งานเชิงพาณิชย์มาอย่างดีแล้ว เช่น Hibernate, Spring และอื่น ๆ รวมทั้งแอพพลิเคชั่นที่สร้างด้วยเกรลส์สามารถรันใน Servlet Container มาตรฐานตั้งแต่ Tomcat ไปจนถึงแอพพลิเคชั่นเซิร์ฟเวอร์ระดับองค์กร เช่น JBoss, Oracle Application Server, WebSphere Application Server หรือ WebLogic Application Server เป็นต้น และแน่นอนว่าเราสามารถนำโค้ดภาษาจาวาที่มีอยู่มาใช้งานร่วมกับเกรลส์ได้ทันที
จุดเด่นของเกรลส์คือความง่ายในการเริ่มใช้งาน นักพัฒนาจาวาจำนวนมากต้องเผชิญหน้ากับความซับซ้อนของการพัฒนาเว็บแอพพลิเคชั่นในจาวา แต่ด้วยเกรลส์ทำให้นักพัฒนาเริ่มต้นได้ง่ายกว่ามาก แต่นั่นก็ไม่ได้หมายความว่าเราจะใช้เกรลส์สร้างระบบขนาดใหญ่ไม่ได้ การใช้งานเกรลส์นั้นจะเริ่มต้นอย่างเรียบง่าย ไม่บังคับให้ผู้พัฒนาออกแบบและสร้างของเกินความจำเป็น และเช่นเดียวกับเฟรมเวิร์คอื่น ๆ ที่พบได้สำหรับการพัฒนาแอพพลิเคชั่นในระดับ Java EE สถาปัตยกรรมแบบ Model-View-Controller หรือ MVC ก็เป็นหัวใจหลักของเกรลส์เนื่องจากได้แรงบันดาลใจมากจากเฟรมเวิร์คยอดนิยมฝั่งภาษารูบี้อย่าง RoR ทำให้ความสามารถของการปรับใช้ MVC อยู่ในระดับเดียวกับ RoR รวมกับพลังของคอมโพเน้นท์ในฝั่งจาวา
เกรลส์สนับสนุนการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ หรือ test-driven development เพราะในปัจจุบัน นักพัฒนาระดับมืออาชีพจะมีทักษะในการเขียนการทดสอบควบคู่ไปกับการพัฒนาโปรแกรม ซึ่งขณะพัฒนาแอพพลิเคชั่นด้วยเกรลส์นั้น โครงของคลาสสำหรับเขียนตัวทดสอบ หรือ unit testing ก็จะถูกสร้างขึ้นมาควบคู่ไปด้วยกันกับคลาสของแอพพลิเคชั่น
เกรลส์ใช้ภาษากรูวี่ในการพัฒนาแอพพลิเคชั่นอย่างที่ได้เกริ่นไปแล้ว โดยกรูวี่เป็นภาษาสริปต์ตามมาตรฐาน JSR-241 ซึ่งทำงานบนจาวาแพล็ตฟอร์ม กรูวี่มีโครงสร้างไวยากรณ์ของภาษาคล้ายคลึงกับภาษาจาวารวมทั้งมีแนวคิดเชิง วัตถุเหมือนกัน จุดเด่นของกรูวี่ก็คือสนับสนุนการสร้างภาษาเฉพาะทาง (Domain Specific Language) ซึ่งกลายเป็นปัจจัยสำคัญให้เกรลส์ได้ใช้ความสามารถของกรูวี่ได้อย่างเต็มที่ แนวคิดเรื่องการใช้ภาษาเฉพาะทางทำให้การสร้างแอพพลิเคชั่นในเกรลส์ง่ายขึ้น ทั้งในแง่ของการพัฒนาและการดูแลรักษา ที่ชัดเจนก็คือเราไม่จำเป็นต้องใช้การปรับแต่ง (configuration) ด้วย XML ในเกรลส์ (แต่ไม่ได้ห้ามที่จะทำหากมีการใช้งานร่วมกับ Spring โดยตรง) ซึ่งจุดนี้เองทำให้สามารถพัฒนาโปรแกรมด้วยภาษาที่กระชับและลดจำนวนบรรทัดใน การโปรแกรมไปได้อย่างมาก
ตัวอย่าง ต่อไปนี้เป็นการสร้างโดเมนคลาสเพื่อต่อกับฐานข้อมูล เป็นตัวอย่างเพียงเพื่อให้เห็นว่าเราสามารถเขียนอธิบายความสัมพันธ์ของ ข้อมูลได้ด้วยภาษาเฉพาะทางที่มีในเกรลส์ หากผู้อ่านสนใจในการเปรียบเทียบจำนวนบรรทัด สามารถลองสร้างคลาสในแบบเดียวกันนี้ด้วยจาวาและ Hibernate หรือ EJB3 เพื่อการเปรียบเทียบได้
class Student { String studentId String name Advisor advisor static hasMany = [registrations: Registrations] }
เกรลส์ยืมปรัชญาสองข้อหลักในการพัฒนามาจาก RoR นั่นก็คือ ดราย-ไม่ซ้ำซ้อน (DRY-Don't Repeat Yourself) และ ข้อตกลงก่อนการปรับแต่ง สำหรับปรัชญาเรื่องไม่ซ้ำซ้อนกล่าวไว้ว่า ควรมีการระบุหรืออธิบายองค์ประกอบในระบบไว้เพียง 1 ที่ต่อ 1 องค์ประกอบเท่านั้น นั่นคือการแก้ไขชิ้นส่วนใด ๆ แอพพลิเคชั่นในเกรลส์จะกระทำได้ในที่ ๆ เดียว ไม่ซ้ำซ้อนในลักษณะที่ต้องไปแก้ไฟล์อื่น ๆ ที่เกี่ยวข้องอีกเป็นต้น ฟังแล้วอาจจะใหม่ในเชิงการพัฒนาโปรแกรม แต่เราอาจรู้จักแนวคิดนี้แล้วในรูปของการทำ normalization ในฐานข้อมูล, XDoclet, XSLT, EJB 3
การใช้ข้อตกลงแทนการปรับแต่งก็หมาย ถึงเกรลส์จะเตรียมกรณีโดยปริยายไว้ให้สำหรับทุก ๆ แง่มุมของการพัฒนาแอพพลิเคชั่น ซึ่งเมื่อทำตามข้อตกลงแล้วก็จะทำให้เราสามารถสร้างแอพพลิเคชั่นได้ด้วยจำนวน บรรทัดที่น้อยกว่าแอพพลิเคชั่นชนิดเดียวกันที่พัฒนาด้วยจาวาที่ใช้การปรับ แต่งด้วย XML และแน่นอนว่าเมื่อต้องการปรับค่าให้แตกต่างไปจากข้อตกลงที่เกรลส์เตรียมไว้ ให้ ก็จะสามารถทำได้ผ่านภาษาเฉพาะทางสำหรับปรับแต่งที่มีในเกรลส์ นอกจากนี้เกรลส์ ยังรวมเทคโนโลยีอีกหลายอย่างเพื่อสนับสนุนการพัฒนาเวบ 2.0 รวมทั้งการทำเวบเซอร์วิสชนิดต่าง ๆ เช่น SOAP และ REST เป็นต้น
ทำไมต้องเป็นเกรล
การพัฒนาเว็บแอปพลิเคชันสักตัวหนึ่งเป็นเรื่องที่ค่อนข้างซับซ้อน แม้กระทั่งเว็บที่ง่ายที่สุดก็ยังต้องทำงานผ่านหลายๆเทียร์ (tier) เริ่มตั้งแต่รับ HTTP request จากผู้ใช้งาน แล้วแกะ HTTP request แปลงลงมาเป็นชนิดข้อมูลแบบต่างๆ หลังจากนั้นมีการตรวจสอบข้อมูล (validate) ว่าข้อมูลที่ได้มาถูกต้อง ทั้งถูกชนิดและมีค่าที่ถูกต้อง หลังจากนั้นก็จัดเก็บลงในตารางในฐานข้อมูล ในขั้นตอนนำข้อมูลออกมาใช้งาน ก็ต้องดึงข้อมูลจากฐานข้อมูล โดยใช้คำสั่ง SQL ได้ข้อมูลเป็น ResultSet แปลงกลับมาเป็น model แล้วนำมาแสดงในรูปแบบ HTML แล้วส่งข้อมูลผ่านโปรโตคอล HTTP
ขั้นตอนข้างต้นจะเกิดขึ้นซ้ำทุกครั้ง ซ้ำแล้วซ้ำเล่า นี่แค่เฉพาะฝั่งเซิร์ฟเวอร์ นี่ยังไม่พูดถึงเรื่องเทคโนโลยีในยุคเว็บ 2.0 พวก client-side JavaScript, AJAX, หรือแม้แต่ RIA
ตลอดมาหลายปี (เกือบๆสิบปี) มีเว็บเฟรมเวิร์คมากมากผุดขึ้นในโลกของจาวา ยกตัวอย่างเช่น Struts, Spring MVC, Stripes, JavaServer Faces ไม่ใช่ว่าเฟรมเวิร์คดังกล่าวไม่ดี เฟรมเวิร์คเหล่านี้ช่วยจัดการงานได้มาก ไม่ว่าจะเป็น mapping request ลง bean, ควบคุม page flow, ช่วยการแสดงผล HTML แต่ในส่วน Object Relational Mapping นักพัฒนายังต้องเฟ้นหาเฟรมเวิร์คที่ทำให้จัดเก็บ object ลงในฐานข้อมูลได้โดยสะดวก ตัวที่เด่นๆก็ได้แก่ Hibernate แต่พอมองในมุมการจัดการล็อกไฟล์ ก็มีตัวเด่นชื่อ Log4j แม้ว่าเฟรมเวิร์คต่างๆเหล่านี้จะช่วยลดภาระนักพัฒนา ไม่ต้องพัฒนาขึ้นใหม่จากศูนย์ไปเสียทุกๆเรื่อง ทำให้การพัฒนาเว็บแอปพลิเคชันที่ซับซ้อน มีขนาดใหญ่ทำได้ง่ายขึ้น แต่กระนั้นเฟรมเวิร์กเหล่านี้ก็ไม่บูรณาการกัน แอปพลิเคชันต้องมีไฟล์คอนฟิคกูเรชั่นมากมายสำหรับแต่ละเฟรมเวิร์คที่ต้องสร้างและดูแลให้อยู่ในสภาพใช้งานได้ (เช่น web.xml, log4j.xml, struts-config.xml, faces-config.xml)
ช่วงต้นๆของโครงการจำนวนไฟล์ต่างๆยังน้อย แต่เมื่อระบบเริ่มเติบโตขึ้น ปัญหาที่มักจะพบบ่อยๆ คือระบบทำงานได้ไม่อย่างที่ออกแบบไว้ นอกเนื่องจากบั๊กแล้วส่วนหนึ่งก็มีปัญหากับคอนฟิคไฟล์เหล่านี้ เป็นเพราะการกำหนดค่าต่างๆในไฟล์เหล่านี้ไม่สอดคล้องกับไฟล์ต่างๆที่เกิด ขึ้น ซึ่งอาจจะเกิดได้ในหรือระหว่าง View หรือ Controller ยกตัวอย่างเช่น เพิ่มหน้าจอใหม่หนึ่งหน้า ต้องสร้างไฟล์หลายชิ้น (อย่างน้อยๆ 3 ได้แก่ view, model, controller) และจะให้ใช้งานได้ ต้องเพิ่มการอ้างอิง artifact เหล่านี้ในคอนฟิคไฟล์หลายที่และในหลายไฟล์ ซึ่งการดูแลไฟล์, ทดสอบระบบ หรือแม้แต่ดีบัก ปัญหาที่คอนฟิคไฟล์เหล่านี้ เป็นเรื่องปวดหัวอย่างมาก
Grails ช่วยนักพัฒนาในหลายๆด้าน ได้แก่
- ลดจำนวนคอนฟิคกูเรชันไฟล์
- เริ่มพัฒนาได้รวดเร็วขึ้น
- ลดช่วงเวลาที่ต้องสูญเสียระหว่างช่วงพัฒนาและทดสอบ
- Consistent development environment
- Domain-specific language for web development
- ลด dependencies
ลดจำนวนคอนฟิคกูเรชันไฟล์
ประโยชน์อันแรกๆของการพัฒนาด้วยเกรล คือใช้แนวคิดแบบแผนเป็นหลัก (convention-based) ทำให้ลดจำนวนไฟล์ที่ต้องกำหนดค่าลงไปได้มาก ปกติการพัฒนาแอปพลิเคชันต้องเสียเวลานั่งกำหนดค่าต่างๆในหลายๆที่ และในหลายๆไฟล์ แม้มีแนวคิด annotation มาใช้ ทำให้ลดความซ้ำซ้อน แต่ยังมีไฟล์ที่ต้องคอนฟิคจากหลายเฟรมเวิร์กอยู่ดี
หลายคนอาจแย้งว่า ปัจจุบันนี้ IDE ฉลาดมากขึ้น มีตัว Wizard หรือ Dialog ช่วยในการกรอกข้อมูลจำพวกนี้ให้อยู่แล้ว เรื่องนี้ไม่ควรเป็นประเด็น แต่ความจริงก็คือ IDE เหล่านั้น แค่ช่วยพรางปัญหาเหล่านี้เท่านั้น แต่ปัญหาความซ้ำซ้อนหรือความต้องการประกาศการเชื่อมโยง กันมีอยู่ อีกทั้งถ้าวันไหนที่ไม่มี IDE นักพัฒนามือใหม่ก็ไม่สามารถไล่หาสาเหตุของปัญหาดังกล่าวได้เอง
สำหรับเกรล มองว่า เมื่อสร้างคลาสขึ้น ตามแบบแผน(convention) คลาสนี้จะถูกเชื่อมโยง (wire)ใน Spring และกลายเป็น entity ของ Hibernate เพื่อพร้อมที่จะคุยกับฐานข้อมูล ตำแหน่งของไฟล์ GSP ที่ใช้แสดงผล สิ่งต่างๆเหล่านี้จะถูกกำหนดชื่อ, ชื่อไฟล์, รวมถึงตำแหน่งโครงสร้างอย่างเป็นระบบโดยอัตโนมัติ แต่เกรลไม่ปิดกั้นการปรับแต่ง ถ้านักพัฒนาไม่ชอบค่าดีฟอล์ทที่กำหนดไว้ สามารถเข้าไปปรับแต่งได้เองเสมอ
เริ่มพัฒนาได้รวดเร็วขึ้น
เกรลมาพร้อมฐานข้อมูลและเซิร์ฟเลตคอนเทนเนอร์ที่บันเดิลมาด้วยกัน เพราะฉะนั้นนักพัฒนาไม่จำเป็นต้องการอะไรนอกจาก JDK แล้วเมื่อติดตั้งเกรลก็พร้อมพัฒนาแอปพลิเคชันได้เลย
นักพัฒนาไม่จำเป็นต้องเสียเวลามานั่งเซ็ตอัพ ไม่ว่าจะเป็นฐานข้อมูล (สร้าง schema, สร้างตาราง) เซิรฟ์เลตคอนเทนเนอร์ (กำหนด context) รวมถึงไม่ต้องนั่งแก้ไข Ant build script เฉพาะแต่ละแอปปลิเคชันกันอีกต่อไป และถึงแม้จะต้องแก้ ก็ลดจำนวนการแก้ไปมาก
หลายคนอาจจะบอกว่า ถ้าระบบลูกค้าใช้ฐานข้อมูลออราเคิล ใช้ WebLogic Server ในการรัน ซึ่งไม่ใช่สิ่งที่เกรลเตรียมไว้ให้ มันจะช่วยอะไรได้ ซึ่งแน่นอนการทดสอบบนเอ็นไวรอนเมนต์จริงเป็นสิ่งที่จำเป็นที่ต้องทำและควรทำแต่เนิ่นๆ แต่มันก็ทำให้นักพัฒนาเรียนรู้เฟรมเวิร์ก และเริ่มต้นพัฒนาระบบงานได้เร็วขึ้น
ลดช่วงเวลาที่ต้องสูญเสียระหว่างช่วงพัฒนาและทดสอบ
เกรลมาพร้อมกับเซิร์ฟเวอร์คอนเทนเนอร์ (Jetty/Tomcat) ซึ่งถูกกำหนดค่าให้ทำงานกับโปรเจกต์เกรล ตัวเกรลเองอาศัยความสามารถ dynamic language จากกรูวี ซึ่งโค้ดกรูวียังรันในจาวาไบต์โค้ดทำให้สามารถทำงานร่วมกับโค้ดจาวาที่มีอยู่แล้วได้
ในโหมดพัฒนา เกรลจะเปิดฟีเจอร์ auto-reloading ซึ่งสามารถแก้ไขโค้ดและเห็นการเปลี่ยนแปลงได้ทันที หรือในระดับไม่กี่วินาที ลดเวลารอคอยที่ความจำเป็นการ re-deploy แอปพลิเคชันหรือแม้กระทั่งรีสตาร์ทเซิร์ฟเวอร์ ซึ่งใช้เวลาระดับนาที เพื่อให้เห็นการเปลี่ยนแปลงที่ใส่เข้าไป เพื่อให้ลดเวลาในการรอคอยในระหว่างช่วงพัฒนาระบบ ซึ่งจะทำให้นักพัฒนาเสียสมาธิและเกิดความหงุดหงิดได้
Consistent development environment
ในการบริหารจัดการโครงการด้านซอฟท์แวร์แล้ว นักพัฒนาในโครงการเดียวกัน ควรจะพัฒนาในแนวทางเดียวกันและมีสภาพแวดล้อมเหมือนกันหมด แต่ในทางปฏิบัติ นักพัฒนาแต่ละคนจะมีจุดเล็กๆน้อยๆที่ไม่เหมือนกัน ยกตัวอย่างเช่น คอนฟิค แอปพลิเคชันเซิร์ฟเวอร์ไว้ต่างกัน, ใช้ดาต้าเบสเซิร์ฟเวอร์ คนละรุ่นกัน เป็นต้น ทำให้ต้องมาเสียเวลาค้นหาสาเหตุและแก้ปัญหา ที่สาเหตุเพียงเพราะคอนฟิคกูเรชันผิด ส่วนเรื่องคอมแพททิเบิลข้ามแอปพลิเคชันเซิร์ฟเวอร์ หรือดาต้าเบสเซิร์ฟเวอร์ ไว้ไปเจอกันตอน integration test
การใช้แบบแผนในเกรลมีประโยชน์อย่างมาก เมื่อสร้างโปรเจกต์ใหม่ในเกรล ระบบจะสร้างโครงสร้างโฟลเดอร์สำหรับการวางไฟล์สำคัญต่างๆไว้ให้ พร้อมสคริปต์สำหรับคอมไฟล์, ทดสอบ, รัน, หรือสร้าง WAR ไฟล์ของโปรเจกต์ โครงสร้างและสคริปต์เหล่านี้จะผ่านการคิด รวบรวม best-practice มาให้ ทำให้เสียเวลาน้อยลงในการวางแผนและเริ่มโปรเจกต์ ทำให้นักพัฒนาสามารถเริ่มงานได้เลย และถ้าจะต้องแก้ไขไฟล์ ก็จะทราบได้ทันทีว่าไฟล์ที่ต้องการเพิ่มหรือแก้ไขจะสามารถหาได้ที่ไหน โดยไม่ต้องถามใคร เพราะโครงสร้างจะเป็นแบบแผนเดียวกันหมด
Domain-specific language for web development
ใครที่มีประสบการณ์การพัฒนาจาวาเว็บแอปพลิเคชัน จะคุ้นเคยกับข้อกำหนดเซิร์ฟเลต เกรลพัฒนาบนพื้นฐานข้อกำหนดเดียวกันเหล่านั้น เพียงแต่ว่ามีการพัฒนาในส่วน Domain Specific Language ขึ้นมาครอบ
เกรลมีการพัฒนาบนพื้นฐานภาษากรูวี ซึ่งมีความสามารถในเรื่อง Domain Specific Language ซึ่งมีการประยุกต์ใช้ในหลายส่วนในเกรล ตั้งแต่เรื่องการทำ Domain class (ทำ object mapping, constraint, association) หรือใน Controller (การจัดการ HTTP request, parameters) ทำให้โค้ดที่ได้จะสั้นและกระชับกว่า
ลด dependencies
สิ่งที่เราจำเป็นต้องในในการเริ่มพัฒนาโปรเจกต์เกรล มีจำนวนน้อยมาก มีเพียงแค่
- จาวา SDK 1.5 ขึ้นไป
- เกรล 1.1 ขึ้นไป
สำหรับกรูวี ไม่ต้องดาว์นโหลดเอง เพราะมันมาพร้อมกับเกรลอยู่แล้ว
เมื่อเปรียบเทียบกับการพัฒนาจาวาเว็บแอปพลิเคชันทั่วๆไปแล้ว เราคงต้องมี
- จาวา SDK
- จาวาเว็บเซิร์ฟเวอร์ ยกตัวอย่างเช่น Tomcat, Jetty, JBoss, Oracle WebLogic Server, Oracle Application Server, WebSphere Server, ...
- ฐานข้อมูล ยกตัวอย่างเช่น HSQLDB, MySQL, Oracle Database, MS SQL Server, IBM DB2, ...
- Object Relational Framework อาจจะเป็นเฟรมเวิร์กที่พัฒนาขึ้นมาใช้เองในหน่วยงาน หรือจะเลือกมาจากสิ่งที่มีอยู่แล้ว เช่น Hibernate, Java Persistence Framework (JPA), EJB Entity Bean
- เว็บเฟรมเวิร์ค เช่น Struts, Spring MVC, ...
- ล็อกเฟรมเวิร์ค เช่น Log4j, Common Logging
- Spring
- View rendering framework เช่น Velocity, Freemarker, ...
ที่ต้องการอันดับต้นๆคือ แอปพลิเคชันเซิร์ฟเวอร์กับฐานข้อมูล ส่วนประกอบอื่นๆก็ยังรอได้ จนกว่าจะต้องใช้ค่อยโหลดมาเพิ่มในโปรเจกต์ (แต่อย่าลืมต้องกำหนดค่าด้วย ไม่ใช่โหลดมาวางเฉยๆแล้วจะเวิร์ก)