Groovy Collections, Closures, and OOP

Harry · 13 Sep 2026 · 2 views

Why This Matters

Collections and closures are core building blocks in Grails. GORM queries, validation rules, data binding, and configuration all lean on them. Getting comfortable here makes your controllers and services both shorter and more readable.

Lists

def users = ["admin", "manager", "employee"]
users << "guest"
println users[0]   // admin

Lists are ordered and mutable by default.

Sets

Sets hold unique values, which makes them perfect for roles and permissions:

def roles = ["ADMIN", "USER", "ADMIN"] as Set
println roles   // [ADMIN, USER]

Maps

def config = [host: "localhost", port: 8080]
println config.host

Maps drive Grails configuration, JSON responses, and constraint definitions.

Iteration

users.each { user -> println user }
users.each { println it }   // implicit "it"

Filtering and Transformation

def adults = users.findAll { it.age >= 18 }
def usernames = users.collect { it.username }

Sorting and Grouping

println numbers.sort()
def byRole = users.groupBy { it.role }

Closures

A closure is a reusable block of code that can capture variables from its surroundings:

def greet = { name -> println "Hello $name" }
greet("Developer")

Closures are passed to GORM queries, validation rules, and event handling throughout Grails.

Classes and Objects

class User {
    String username
    String email
}

def user = new User(username: "admin", email: "admin@grails.com")

Inheritance

class Person { String name }
class Employee extends Person { String employeeId }

Interfaces and Traits

Traits are powerful in Grails because owners allow horizontal reuse of behavior:

trait Timestamped {
    Date dateCreated
    Date lastUpdated
}

class Product implements Timestamped {
    String name
}

OOP Best Practices in Grails

  • Keep domain classes focused on data and rules.
  • Move business logic to services.
  • Use traits for shared behavior like auditing.
  • Avoid deep inheritance hierarchies; prefer composition.

Common Mistakes

  • Putting too much logic in domain classes.
  • Overusing inheritance.
  • Ignoring how Grails binds data from request params.
  • Not leveraging traits where they fit.

Key Points

  • Lists, sets, and maps have native literals.
  • findAll, collect, sort, and groupBy cover most data work.
  • Closures appear everywhere in Grails APIs.
  • Traits are the preferred way to share behavior.
  • Favor composition over deep inheritance.
Share this post:

Comments (0)

Please login or register to comment.