Más contenido relacionado
Cleaner and Leaner Groovy
- 2. @BUILDER
@Builder
class Premise {
def sqFeet
def occupants
def stories
def heatingType
def coolingType
def homeType
def yearBuilt
}
def premise = Premise.builder()
.sqFeet(1200)
.occupants(4)
.stories(2)
.heatingType('Furnace·(Gas)')
.coolingType('Central·Air·Conditioning')
.homeType('Single·Family·(detached)')
.yearBuilt(1995).build()
© Rowell Belen
- 3. @TOSTRING
@ToString(includeNames=true, ignoreNulls = true, excludes="ssn")
class Customer {
String first, last
int age
Collection favItems
String ssn
}
def customer =
new Customer(first:'Tom', last:'Jones', age:21, favItems:['Books', 'Games'], ssn:'xxx-xx-xxxxx')
assert customer.toString() ==
'Customer(first:Tom, last:Jones, age:21, favItems:[Books, Games])'
© Rowell Belen
- 6. @LAZY
class App {
@Lazy
AuthService authService = { ctx.getBean('AuthService.class') }()
@Lazy // defer expensive initialization
ApplicationContext ctx =
{ new AnnotationConfigApplicationContext(AppConfig.class) }()
@Lazy
UserService userService
Profile getProfile(user){
authService.login(user)
userService.findProfile(user)
}
}
© Rowell Belen
- 7. @IMMUTABLE
@Immutable
class User {
String email
Collection roles
}
def u = new User(email: 'email@host.com', roles: ['admin', 'user'])
// Properties are readonly.
shouldFail(ReadOnlyPropertyException) {
u.email = 'new@email.com'
}
// Collections are also wrapped in immutable wrapper classes
shouldFail(UnsupportedOperationException) {
u.roles << 'new role'
}
© Rowell Belen
- 9. @DELEGATE
class NoisySet {
@Delegate
Set delegate = new HashSet()
@Override
boolean add(item) {
println "adding $item"
delegate.add(item)
}
}
def ns = new NoisySet()
ns.add(1)
ns.addAll([2, 3])
assert ns.size() == 3
© Rowell Belen
- 11. @AUTOCLONE
@AutoClone
class Chef {
String name
List<String> recipes
}
def name = 'Gordon Ramsay'
def recipes = ['Snail porridge', 'Bacon & egg ice cream']
def c1 = new Chef(name: name, recipes: recipes)
def c2 = c1.clone()
assert c2.recipes == recipes
© Rowell Belen
- 13. @CATEGORY - OVERRIDE
class Energy {
def usage(){ .. } // return joules
}
@Category(Energy)
class Therms {
def usage(){ .. } // override - return therms
}
use(Therms){
def energy = new Energy()
energy.usage() // returns usage in Therms
}
© Rowell Belen
- 14. @CATEGORY - ENHANCE
class Energy {
def usage(){ .. } // return joules
}
@Category(Energy)
class KilowattHour {
def kwUsage(){ .. } // enhance with new method - return usage in kWh
}
use(KilowattHour){
def energy = new Energy()
energy.usage() // returns in joules
energy.kwUsage() // returns in kWh
}
© Rowell Belen
- 16. @WITHREADLOCK / @WITHWRITELOCK
class PhoneBook {
private final phoneNumbers = [:]
// multiple readers can access simultaneously
// unless lock is obtained by writer
@WithReadLock
def getNumber(key) {
phoneNumbers[key]
}
// readers will block until lock is released by the writer
@WithWriteLock
def addNumber(key, value) {
phoneNumbers[key] = value
}
}
© Rowell Belen
- 17. Concurrent Map/Filter/Reduce Example
import static groovyx.gpars.GParsPool.withPool
withPool {
def numbers = [1, 2, 3, 4, 5, 6]
assert [1, 4, 9] == numbers.parallel
.map { it * it }
.filter { it < 10 }
.collection
}
withPool {
assert 55 == [0, 1, 2, 3, 4].parallel
.map { it + 1 }
.map { it ** 2 }
.reduce { a, b -> a + b }
}
withPool(10) {...}
withPool(20, exceptionHandler) {...}
© Rowell Belen
- 18. Parallel Collections
withPool {
def numbers = [1, 2, 3, 4, 5, 6]
// dynamically enhanced with parallel processing capabilities
numbers.eachParallel{ .. }
numbers.eachWithIndexParallel{ .. }
numbers.collectParallel{ .. }
numbers.findAllParallel{ .. }
numbers.findAnyParallel{ .. }
numbers.findParallel{ .. }
numbers.everyParallel{ .. }
numbers.anyParallel{ .. }
numbers.grepParallel{ .. }
numbers.groupByParallel{ .. }
numbers.foldParallel{ .. }
numbers.minParallel{ .. }
numbers.maxParallel{ .. }
numbers.sumParallel{ .. }
numbers.splitParallel{ .. }
numbers.countParallel{ .. }
numbers.foldParallel{ .. }
}
© Rowell Belen
- 19. Implicit Task Coordination
def getDashboardData(req) {
def results = new Dataflows()
// These 3 tasks will execute in parallel
task {
results.user = fetchUserData(req)
}
task {
results.weather = fetchWeatherData(req)
}
task {
results.savings = fetchSavingsData(req)
}
// Blocks until results.user is bound
task {
results.devices = fetchDevices(req, results.user.defaultDevice)
}
results
}
© Rowell Belen