เหตุใดนักพัฒนา Java จึงควรให้โอกาสแก่ Grails
เผยแพร่แล้ว: 2022-03-11Java มีระบบนิเวศที่เติบโตเต็มที่ตลอดหลายปีของการพัฒนา ทำให้ Java มีแพลตฟอร์มที่น่าเชื่อถือที่สุดแห่งหนึ่ง แต่ยังขาดวิธีการที่จำเป็นในการทำงานให้เสร็จอย่างรวดเร็ว โดยเฉพาะอย่างยิ่งสำหรับสิ่งต่างๆ เช่น เว็บแอปพลิเคชัน ในความพยายามที่จะหลีกเลี่ยงความผิดหวังกับปัญหาประเภทนี้ นักพัฒนามักจะเลือกใช้ภาษาในการนำไปใช้และเฟรมเวิร์กเว็บที่ทันสมัยแทน เช่น Ruby with Ruby on Rails, Python กับ Django และอื่นๆ ซึ่งแตกต่างจาก Java สิ่งเหล่านี้ให้เส้นทางที่คล่องตัวมากขึ้นในการสร้างเว็บแอปพลิเคชัน
โชคดีสำหรับนักพัฒนา Java ที่ต้องการสร้างเว็บแอปพลิเคชัน มี วิธีที่ดีกว่าและเกี่ยวข้องกับ Grails ในบทความนี้ เราจะมาดูกันว่า Grails กับ Groovy เป็นทางเลือกที่ใช้งานได้จริงในขอบเขต JVM อย่างไร เราจะมาดูตัวอย่างที่ Grails ดึงดูดใจเราในฐานะนักพัฒนา Java และอาจดึงดูดให้คนอื่นลองดูด้วย
เรื่องราว
ในการเริ่มต้นที่ฉันทำงานให้ เรามีปัญหาตรงนี้ เรามีแอปพลิเคชั่น Spring ซึ่งใช้งานยาก ด้วยขนาดที่ใหญ่ขึ้นเรื่อย ๆ เราจึงพบว่าการปรับโครงสร้างใหม่และเพิ่มฟังก์ชันการทำงานทำให้เราใช้เวลานานกว่าที่ควรจะเป็น เมื่อรวมกับแรงจูงใจอื่นๆ ทำให้เราตัดสินใจเขียนแอปพลิเคชันหลักของเราใหม่ นอกจากนี้เรายังเปิดรับการเปลี่ยนแปลงหรือแทนที่กลุ่มเทคโนโลยีที่มีอยู่ Grails ดูเหมือนจะเป็นตัวเลือกที่ทำงานได้เนื่องจากทำงานใน JVM และสร้างขึ้นจากเทคโนโลยีที่เรารู้อยู่แล้ว มันใช้ภาษาการเขียนโปรแกรม Groovy แต่ในขณะเดียวกันก็อนุญาตให้คุณผสมกับ Java ดังนั้นเราจึงกระโดด
เดินหน้าเต็มกำลัง
สิ่งหนึ่งที่ Grails เชี่ยวชาญมากคือการทำให้ง่ายต่อการเริ่มโครงการใหม่ มันง่ายพอๆ กับการรันคำสั่งที่สร้างโครงสร้างโปรเจ็กต์พร้อมโฟลเดอร์ทั้งหมดที่จำเป็นสำหรับคลาสที่คุณจะเพิ่มในภายหลัง การเพิ่มคลาสโมเดล ตัวควบคุม บริการ และหน้าเว็บนั้นใช้ความพยายามเพียงเล็กน้อยเช่นเดียวกัน สิ่งเดียวที่คุณต้องดูแลคือการตั้งชื่อและวางสิ่งต่างๆ ให้ถูกต้อง ต่างจาก Java ตรงที่ไม่มีโค้ดสำเร็จรูปที่จำเป็นต้องมีเพียงเพราะจำเป็นต้องมี สิ่งนี้เกิดขึ้นได้บางส่วนโดยใช้ Spring และ Hibernate ซึ่งเป็นเสาหลักสองประการของ Grails รวมถึงแนวคิดของการเข้ารหัสตามแบบแผน ในการรันโครงการ Grails มาพร้อมกับ Apache Tomcat เป็นเซิร์ฟเวอร์การพัฒนา สิ่งที่เราต้องทำคือเรียกใช้โครงการใน IDE ของเราและเซิร์ฟเวอร์จะทำงานด้วยโค้ดของเราที่ปรับใช้ นอกจากนี้ Grails' Object Relational Mapping (GORM) กับ Hibernate จะดูแลการสร้างฐานข้อมูลให้เราด้วย ในการใช้ฐานข้อมูลที่มีอยู่ เราต้องกำหนดค่าคุณสมบัติการเชื่อมต่อ JDBC หรือปล่อยให้เป็นค่าเริ่มต้นเพื่อใช้อินสแตนซ์ในหน่วยความจำ เมื่อเซิร์ฟเวอร์ที่มี Grails ทำงานอยู่ (ใช้เวลามากกว่าแอปพลิเคชัน Spring MVC เล็กน้อย) เราสามารถแก้ไขโค้ดและฟังก์ชันการปรับใช้ด่วนจะทำให้เซสชันการดีบักของเราติดตั้งเวอร์ชันล่าสุด คลาสเดียวที่ไม่สามารถโหลดซ้ำด้วยวิธีนี้คือคลาสเอนทิตี
การเติมฐานข้อมูลสามารถทำได้โดยใช้สคริปต์ SQL แต่อาจเป็นเรื่องที่น่าเบื่อหน่าย โปรเจ็กต์ของ Grails ทั้งหมดมีคลาส Bootstrap ซึ่งจะถูกเรียกใช้เมื่อรันแอปพลิเคชันของเรา ในคลาสนี้ เราสามารถจัดเก็บหรือแก้ไขข้อมูลและทำให้เริ่มต้นสถานะแอปพลิเคชันของเราได้ สิ่งนี้พิสูจน์แล้วว่ามีประโยชน์มากสำหรับเรา ดังนั้นเราจึงมีกรณีทดสอบในเวอร์ชันพัฒนาทันที
การจัดการข้อมูล
สิ่งหนึ่งที่ดึงดูดความสนใจของเราในทันทีด้วย Grails คือความง่ายในการทำงานกับข้อมูล การอ่านจากฐานข้อมูลเป็นงานที่ต้องทำซ้ำแล้วซ้ำอีก และหลายครั้งก็เป็นเรื่องง่าย เช่นเดียวกับการดึงเอนทิตีตั้งแต่หนึ่งรายการขึ้นไปที่ตรงตามเกณฑ์ที่กำหนดแล้วจึงรวมเข้าด้วยกัน ทำไมไม่ใช้ตัวค้นหาแบบไดนามิกสำหรับสิ่งนั้น? เป็นวิธีการสืบค้นข้อมูลที่มีการสร้างวิธีการแบบไดนามิกในขณะใช้งานจริง สิ่งที่คุณต้องทำคือทำตามแบบแผนการตั้งชื่อ
def users = User.findAllByLastNameLikeOrAgeGreaterThan('Doe%', 30)
บรรทัดด้านบนจะดึงวัตถุ User ทั้งหมดที่มีนามสกุลขึ้นต้นด้วย “Doe” หรืออายุมากกว่า 30 ใช่ ไม่ใช่กรณีที่ซับซ้อนมาก แต่คุณจะได้รับส่วนสำคัญ
จะเป็นอย่างไรถ้าเราต้องการกรองรายการนี้เพิ่มเติมสำหรับรายการที่มีคุณสมบัติ “failedLogins” มากกว่า 10 แล้วถ้าเราต้องการจัดเรียงตามวันที่สร้างล่ะ? แล้วถ้าเราต้องการรวมชื่อแรกของพวกเขาเข้าด้วยกันหรือค้นหาอายุสูงสุดของผู้ใช้ที่ส่งคืนล่ะ
users = users.findAll() { it.failedLogins > 10 } users = users.sort { it.dateCreated } def firstNamesString = users.firstName.join(', ') def maximumAge = users.age.max()
ตัวอย่างข้างต้นอาจดูเรียบง่าย แต่แสดงให้เห็นว่า Grails มีประสิทธิภาพเพียงใดในการสืบค้น กรอง และจัดการข้อมูล ใน Java 8 คุณสามารถบรรลุผลลัพธ์ที่คล้ายคลึงกันสำหรับบางกรณีเหล่านี้ แต่จะยังคงต้องการโค้ดมากกว่า Grails
บางครั้งฉันต้องการสร้างความแตกต่าง
ตัวสร้างไดนามิกหรือตัวสร้างอาร์กิวเมนต์ที่มีชื่อเป็นคุณลักษณะที่พวกเราหลายคนต้องการมีใน Java เป็นการดีที่จะกำหนดว่าคอนสตรัคเตอร์ตัวใดที่คลาสบางคลาสอนุญาต แต่ในหลายกรณี คุณเพียงแค่ต้องการตั้งค่าคุณสมบัติบางอย่างและรับอินสแตนซ์สาปแช่ง Groovy เพิ่มคอนสตรัคเตอร์พิเศษสำหรับแต่ละเอนทิตี ซึ่งโดยทั่วไปจะใช้ความสง่างามของแผนที่เป็นอินพุต และตั้งค่าคุณสมบัติด้วยรายการแผนที่
def Person = new Person(name: 'Batman', age: 57)
แนวทางนี้นำไปสู่โค้ดที่สื่อความหมายได้ชัดเจนกว่ามาก และหลีกเลี่ยงความจำเป็นในโค้ดสำเร็จรูปของคอนสตรัคเตอร์ทั้งหมด
และ BTW นี่คือตัวอย่างบางส่วนของความยอดเยี่ยมและความสง่างามของแผนที่ของ Groovy:
def emptyMap = [:] def map = [bread:3, milk:5, butter:2] map['bread'] = 4 map.milk = 6
นี่เป็นอีกตัวอย่างหนึ่งของโค้ดที่สั้นและเรียบง่ายแต่ทรงพลัง โดยจะแสดงวิธีการใช้การเริ่มต้นแบบอินไลน์และวิธีจัดการค่าแผนที่ในลักษณะที่คล้ายกับคุณสมบัติของอ็อบเจ็กต์ ไม่จำเป็นต้องเรียกใช้วิธีการ Java แบบดั้งเดิมสำหรับการจัดการขั้นพื้นฐาน เว้นแต่ว่าคุณต้องการจริงๆ
เราต้องการพลังมากกว่านี้!
แน่นอนว่าไม่มีกรอบงานใดที่สามารถทำทุกอย่างได้ แต่เมื่อเราอุดช่องว่าง เราควรดูว่ามีอะไรอีกบ้างที่มีอยู่ก่อนที่จะพยายามใช้โซลูชันของเราเอง ในการขยายคลังแสงของฟังก์ชันที่ใช้ Grails เราสามารถใช้ Grails Plugins การติดตั้งปลั๊กอินทำได้โดยการเพิ่มบรรทัดอื่นในคลาส BuildConfig
ที่มีอยู่ในทุกโปรเจ็กต์ของ Grails (การประชุมโค้ดหยุดทำงานอีกครั้ง!)

compile ':spring-security-core:2.0-RC4'
บรรทัดด้านบนเพิ่มแกนความปลอดภัย Spring ให้กับแอปพลิเคชันของเรา และแทบไม่มีการกำหนดค่าเพิ่มเติมที่จำเป็นในการรวมฟังก์ชันนี้
ที่กล่าวว่าให้ฉันบอกคุณเกี่ยวกับกรณีที่เราต้องจัดการกับ เราจำเป็นต้องใช้การค้นหาที่ครอบคลุมเอนทิตีข้อมูลหลายรายการ Grails มีปลั๊กอิน Elasticsearch ซึ่งใช้งานง่าย ดังที่ได้กล่าวไว้ก่อนหน้านี้ เราต้องการเพียงแค่อ้างอิงปลั๊กอินในไฟล์ปรับแต่งเท่านั้น และเราพร้อมแล้วที่จะไป หากเราต้องการค้นหาเอนทิตีของคลาสใดคลาสหนึ่ง เราเพียงแค่เพิ่มคุณสมบัติ "ค้นหาได้" แบบคงที่ให้กับคลาสนั้น และหากต้องการ เราสามารถจำกัดคุณสมบัติที่จะอนุญาตให้ค้นหาได้
class User { static searchable = { only = name } String name Double salary }
เป็นโค้ดที่น้อยมาก แต่ภายใต้ประทุน Grails และปลั๊กอิน Elasticsearch จะสร้างดัชนีผู้ใช้ทั้งหมดโดยอัตโนมัติตามชื่อ และทำให้เราสามารถค้นหาด้วยชื่อได้ การโทรค้นหาจริงยังรัดกุมมาก:
User.search("${params.query}")
ถ้าเราไม่ต้องการ เราจะไม่ต้องแตะดัชนี Lucene ทั้งหมดจะทำโดยอัตโนมัติอย่างน่าอัศจรรย์สำหรับเรา ปลั๊กอินยังมี API สำหรับแสดงผลการค้นหา ซึ่งสามารถเน้นการจับคู่ที่พบในข้อความที่ค้นหา นี่เป็นเพียงตัวอย่างที่ปลั๊กอินสามารถจัดเตรียมชุดฟังก์ชันการทำงานจำนวนมาก ซึ่งจะทำให้เรามีประสิทธิภาพมากขึ้นโดยไม่จำเป็นต้องติดตั้งเอง
เรายังต้องการพลังมากกว่านี้
ปลั๊กอินนั้นยอดเยี่ยม แต่บางครั้งเราไม่ต้องการปลั๊กอินทั้งหมด เราแค่ต้องการบางอย่างเพิ่มเติม คุณจำครั้งสุดท้ายที่คุณต้องการมีวิธีการเพิ่มเติมในคลาส Java ที่มีอยู่ แต่คุณไม่ต้องการ (หรือไม่สามารถ) ขยาย / แทนที่ได้อย่างไร ใน Groovy คุณสามารถเพิ่มเมธอดและคุณสมบัติให้กับคลาสที่มีอยู่ หรือแม้แต่บางอินสแตนซ์ของคลาสเหล่านั้นได้ ตัวอย่างเช่น คุณสามารถเพิ่มวิธีการ formatting
ให้กับคลาส java.util.Date
ซึ่งยอดเยี่ยมเมื่อคุณต้องการจัดรูปแบบวันที่อย่างสม่ำเสมอและเพียงแค่ไม่ต้องการเขียนคลาส util แบบคงที่หรือกำหนดตัวกรองต่างๆ
Date.metaClass.formatDate = { delegate.format("dd.MM.yyyy") }
จะเป็นอย่างไรถ้าคุณต้องการจัดเรียงรายชื่อผู้ใช้ตามค่าที่คำนวณได้ และคุณต้องการเพียงกรณีเดียวเท่านั้น (เช่น การเพิ่มวิธีการใหม่ในคลาสผู้ใช้จะทำให้เกิดมลพิษ) คุณสามารถเพิ่มคุณสมบัติในแต่ละอินสแตนซ์เหล่านั้น จากนั้นเพียงแค่จัดเรียงหรือกรองคอลเลกชันตามคุณสมบัตินั้น:
user.metaClass.computedProp = 312 * 32 * 3
ผู้เขียน Groovy ได้เพิ่มการปรับปรุงมากมายให้กับคลาส Java หลักบางคลาสแล้ว ดังนั้นเราจึงไม่จำเป็นต้องทำ ด้านล่างนี้เป็นตัวอย่างบางส่วน
ใช้ “ลบ” เพื่อลบองค์ประกอบทั้งหมดออกจากคอลเลกชันที่มีอยู่ในคอลเลกชันอื่น
assert [1, 2, 3, 4, 4, 5] - [2, 4] == [1, 3, 5]
วิธีการเพิ่มเติมสำหรับการจัดการวัตถุ java.util.Date
ซึ่งสะดวกหลายครั้ง เช่น การเพิ่ม/ลบวันจากวันที่ หรือการรับ/ตั้งค่าฟิลด์เฉพาะของวันที่โดยไม่ต้องแปลงเป็น Calendar
หรือใช้ไลบรารีเพิ่มเติม
def yesterdayAllMyTroublesSeemedSoFarAway = new Date() - 1 def myAwesomeAnniversaryYear = myAwesomeDate[Calendar.YEAR] + 1 myAwesomeDate.set(year: myAwesomeAnniversaryYear, second: 0)
เมื่อคุณต้องการอธิบายเกี่ยวกับการจัดการวันที่จริงๆ คุณสามารถใช้คลาส TimeCategory
ที่เพิ่ม Groovy ได้:
use (TimeCategory) { println 1.minute.from.now println 10.hours.ago def someDate = new Date() println someDate - 3.months }
ค้อนกับตะปู
จากนั้นก็มี IDE GGTS ที่ใช้ Eclipse และ IntelliJ IDEA ได้รับการตั้งค่าสำหรับการทำงานกับ Grails พวกเขาเข้าใจโครงสร้างโครงการ (และจะช่วยให้คุณนำทางผ่านโฟลเดอร์และทรัพยากร) และมีทางลัดสำหรับคำสั่งที่คุณจะใช้บ่อยที่สุด (เช่น เพิ่มตัวควบคุม เพิ่มหน้า เรียกใช้โครงการ ฯลฯ) ด้วย Grails คุณจะรันคำสั่ง (เพื่อรันโปรเจ็กต์หรือตั้งค่าฟังก์ชันปลั๊กอินใหม่) และคุณจะต้องมีการกำหนดค่าที่แตกต่างกัน ซึ่ง IDE ครอบคลุมด้วย การเติมโค้ดให้สมบูรณ์ทำงานได้ดีในหน้าเทมเพลตเว็บของ Grails ซึ่งคุณมักจะอ้างอิงถึงคอนโทรลเลอร์และการดำเนินการ นอกจากนี้ยังมี IDE อื่นๆ ที่สามารถใช้กับ Grails ได้ เช่น Netbeans, TextMate, Emacs และอื่นๆ
แล้วด้านมืดล่ะ?
เช่นเดียวกับทุกสิ่งทุกอย่างในชีวิต มีข้อแม้สำหรับ Grails ด้วย มีเวทมนตร์มากมายที่ต้องทำภายใต้ประทุนซึ่งมักจะเป็นสิ่งที่ดี แต่บางครั้งผลลัพธ์อาจไม่เป็นอย่างที่คุณคาดหวัง ข้อบกพร่องจะเกิดขึ้นเพียงเพราะไม่ได้ใช้การพิมพ์ (ใช่ ประเภทเป็นตัวเลือกใน Groovy) และไม่ระมัดระวังเพียงพอ และบางทีคุณจะไม่สังเกตเห็นข้อผิดพลาดจนกว่าจะสายเกินไป นอกจากนี้ การเขียนเพียงคำเดียวเพื่อสร้างความประทับใจให้เพื่อนร่วมงานเป็นเรื่องที่น่าดึงดูดใจ และตัวคุณเอง. แต่โค้ดที่ทรงพลังเหล่านี้อาจไม่สามารถอธิบายตนเองได้สำหรับเพื่อนร่วมงานของคุณ หรือแม้แต่ตัวคุณเองในสองสามเดือน นั่นเป็นเหตุผลที่ฉันคิดว่า Grails ต้องการวินัยในการเขียนโปรแกรมมากกว่าเฟรมเวิร์กดั้งเดิมบางตัว
เวลาคือเงิน
การเข้ารหัสไม่ควรใช้เวลานานเพียงเพราะเฟรมเวิร์กปัจจุบันของคุณต้องการ โดยเฉพาะอย่างยิ่งเมื่อมีบริษัทสตาร์ทอัพจำนวนมากขึ้นเรื่อยๆ ในปัจจุบัน สิ่งสำคัญคือต้องให้ความสำคัญกับงานที่สำคัญจริงๆ และมีประสิทธิภาพมากที่สุด เวลาคือเงินและเวลาสู่ตลาดเป็นสิ่งสำคัญ คุณต้องสามารถดำเนินการได้อย่างรวดเร็วและนำโซลูชันไปใช้ก่อนหมดเวลาและคู่แข่งของคุณเอาชนะคุณได้
เพื่อนของฉันที่ทำงานกับ Ruby on Rails หรือ Python/Django บอกฉันมานานแล้วว่าเทคโนโลยีเหล่านั้นเจ๋งแค่ไหน และมันรู้สึกงี่เง่าจริงๆ ที่คิดว่าฉันต้องใช้เวลามากขึ้นใน Java ในการเขียนโค้ดที่เก็บบางอย่างในฐานข้อมูลและแสดงในหน้าเว็บ Grails อาจเป็นคำตอบที่มีประโยชน์ ไม่ใช่ว่าคุณทำไม่ได้กับ Java, Spring MVC และ Hibernate ล้วนๆ คุณสามารถ แอปพลิเคชันของคุณอาจทำงานเร็วขึ้นเล็กน้อย แต่คุณจะทำงานเสร็จเร็วขึ้นด้วย Grails