SlideShare uma empresa Scribd logo
1 de 83
Baixar para ler offline
Groovy
Refactoring Patterns
Naresha K

@naresha_k

https://blog.nareshak.com/
About me
Developer, Coach, Consultant
Founder & Organiser
Bangalore Groovy User Group
Refactoring
noun: a change made to the internal structure
of software to make it easier to understand
and cheaper to modify without changing its
observable behaviour
verb: to restructure software by applying
a series of refactorings without changing
its observable behaviour.
Refactoring
https://refactoring.com/
Red Green
Refactor
TDD
Address Common Code Smells
A code smell is a surface indication that
usually corresponds to a deeper problem in
the system. The term was first coined by Kent
Beck while helping me with
my Refactoring book.
~ Martin Fowler
https://martinfowler.com/bliki/CodeSmell.html
{ Code Smells }
Long Methods
Duplicated Code Large Class
Long Param List
Primitive Obsession
Data Class
Inappropriate Intimacy
int calculateM1(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue + 1
}
int calculateM2(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue * 2
}
int calculateM1(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue + 1
}
int calculateM2(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue * 2
}
Duplicate Code
Reinventing the wheel
int calculateM1(int value1, int value2, int value3) {
Math.max(value1, Math.max(value2, value3)) + 1
}
int calculateM2(int value1, int value2, int value3) {
Math.max(value1, Math.max(value2, value3)) * 2
}
int calculateM1(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue + 1
}
int calculateM2(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue * 2
}
int calculateM1(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue + 1
}
int calculateM1(int value1, int value2, int value3) {
int maxValue = max(value1, value2, value3)
maxValue + 1
}
private int max(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue
}
Extract
Method
int calculateM1(int value1, int value2, int value3) {
int maxValue = max(value1, value2, value3)
maxValue + 1
}
private int max(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue
}
int calculateM2(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue * 2
}
int calculateM1(int value1, int value2, int value3) {
int maxValue = max(value1, value2, value3)
maxValue + 1
}
private int max(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue
}
int calculateM2(int value1, int value2, int value3) {
int maxValue = max(value1, value2, value3)
maxValue * 2
}
private int max(int value1, int value2, int value3) {
int maxValue
if (value1 > value2 && value1 > value3) {
maxValue = value1
} else if (value2 > value3) {
maxValue = value2
} else {
maxValue = value3
}
maxValue
}
private int max(int value1, int value2, int value3) {
Math.max(value1, Math.max(value2, value3))
}
private int max(int value1, int value2, int value3) {
Math.max(value1, Math.max(value2, value3))
}
int calculateM1(int value1, int value2, int value3) {
int maxValue = max(value1, value2, value3)
maxValue + 1
}
int calculateM2(int value1, int value2, int value3) {
int maxValue = max(value1, value2, value3)
maxValue * 2
}
private int max(int value1, int value2, int value3) {
Math.max(value1, Math.max(value2, value3))
}
int calculateM1(int value1, int value2, int value3) {
int maxValue = Math.max(value1, Math.max(value2, value3))
maxValue + 1
}
int calculateM2(int value1, int value2, int value3) {
int maxValue = Math.max(value1, Math.max(value2, value3))
maxValue * 2
}
Inline Method
int calculateM1(int value1, int value2, int value3) {
int maxValue = Math.max(value1, Math.max(value2, value3))
maxValue + 1
}
int calculateM2(int value1, int value2, int value3) {
int maxValue = Math.max(value1, Math.max(value2, value3))
maxValue * 2
}
int calculateM1(int value1, int value2, int value3) {
Math.max(value1, Math.max(value2, value3)) + 1
}
int calculateM2(int value1, int value2, int value3) {
Math.max(value1, Math.max(value2, value3)) * 2
}
Inline
Variable
Importance of small steps
in refactoring
List<Integer> numbers = [1, 2, 3, 4, 5]
for(number in numbers) {
println number
}
External Iterator
To
Internal Iterator
List<Integer> numbers = [1, 2, 3, 4, 5]
for(number in numbers) {
println number
}
List<Integer> numbers = [1, 2, 3, 4, 5]
numbers.forEach { println it }
List<Integer> numbers = [1, 2, 3, 4, 5]
numbers.forEach(System.out.&println)
Refactoring to
Idiomatic Groovy
def numbers = [1, 2, 3, 4, 5]
for(number in numbers) {
println number
}
def numbers = [1, 2, 3, 4, 5]
numbers.each { println it }
def evenNumbers = []
numbers.each { number ->
if (number % 2 == 0) {
evenNumbers << number
}
}
def evenNumbers = numbers
.findAll { it % 2 == 0}
def sum = 0
numbers.each {
sum += it
}
def sum = numbers.inject(0,
{ result, number -> result + number }
)
List<Integer> numbers = [1, 2, 3, 4, 5]
def result = [:]
numbers.forEach { number ->
result[number] = number * number
}
List<Integer> numbers = [1, 2, 3, 4, 5]
def result = numbers.collectEntries {
[it, it * it]
}
List<Integer> numbers = [1, 2, 3, 4, 5]
def evenNumbers = numbers.findAll { it % 2 == 0}
Extract Closure
List<Integer> numbers = [1, 2, 3, 4, 5]
def evenNumbers = numbers.findAll { it % 2 == 0}
List<Integer> numbers = [1, 2, 3, 4, 5]
def evenNumbers = numbers.findAll({ it % 2 == 0 })
List<Integer> numbers = [1, 2, 3, 4, 5]
def isEven = { it % 2 == 0 }
def evenNumbers = numbers.findAll(isEven)
Inline Closure
List<Integer> numbers = [1, 2, 3, 4, 5]
def isEven = { it % 2 == 0 }
def evenNumbers = numbers.findAll(isEven)
List<Integer> numbers = [1, 2, 3, 4, 5]
def evenNumbers = numbers.findAll { it % 2 == 0}
def numbers = [1, 2, 3, 4, 5]
def sumOfSuqaresOfEvenNumbers = 0
numbers.forEach { number ->
if(number % 2 == 0 ){
sumOfSuqaresOfEvenNumbers += number * number
}
}
To Functional Style
def numbers = [1, 2, 3, 4, 5]
def sumOfSuqaresOfEvenNumbers = 0
numbers.forEach { number ->
if(number % 2 == 0 ){
sumOfSuqaresOfEvenNumbers += number * number
}
}
def sumOfSuqaresOfEvenNumbers = numbers
.findAll { it % 2 == 0 }
.collect { it * it }
.sum()
def numbers = [1, 2, 3, 4, 5]
def sumOfSuqaresOfEvenNumbers = 0
numbers.forEach { number ->
if(number % 2 == 0 ){
sumOfSuqaresOfEvenNumbers += number * number
}
}
def square = { it * it }
def sumOfSuqaresOfEvenNumbers = 0
numbers.forEach { number ->
if(number % 2 == 0 ){
sumOfSuqaresOfEvenNumbers += square(number)
}
}
def square = { it * it }
def sumOfSuqaresOfEvenNumbers = 0
numbers.forEach { number ->
if(number % 2 == 0 ){
sumOfSuqaresOfEvenNumbers += square(number)
}
}
def sumOfSuqaresOfEvenNumbers = 0
def evenNumbers = numbers.findAll { it % 2 == 0}
evenNumbers.forEach { number ->
sumOfSuqaresOfEvenNumbers += square(number)
}
def sumOfSuqaresOfEvenNumbers = 0
def evenNumbers = numbers.findAll { it % 2 == 0}
evenNumbers.forEach { number ->
sumOfSuqaresOfEvenNumbers += square(number)
}
def sumOfSuqaresOfEvenNumbers = 0
def evenNumbers = numbers.findAll { it % 2 == 0}
def squaresOfEvenNumbers = evenNumbers.collect(square)
squaresOfEvenNumbers.forEach { number ->
sumOfSuqaresOfEvenNumbers += number
}
def square = { it * it }
def evenNumbers = numbers.findAll { it % 2 == 0 }
def squaresOfEvenNumbers = evenNumbers
.collect ( square )
def sumOfSuqaresOfEvenNumbers = squaresOfEvenNumbers.sum()
def sumOfSuqaresOfEvenNumbers = 0
def evenNumbers = numbers.findAll { it % 2 == 0}
def squaresOfEvenNumbers = evenNumbers.collect(square)
squaresOfEvenNumbers.forEach { number ->
sumOfSuqaresOfEvenNumbers += number
}
def square = { it * it }
def evenNumbers = numbers.findAll { it % 2 == 0 }
def squaresOfEvenNumbers = evenNumbers
.collect ( square )
def sumOfSuqaresOfEvenNumbers = squaresOfEvenNumbers.sum()
def sumOfSuqaresOfEvenNumbers = numbers
.findAll { it % 2 == 0 }
.collect (square)
.sum()
Inline
class Multiplier {
private final int times
Multiplier(int times) {
this.times = times
}
int multiply(int number) {
times * number
}
}
Multiplier doubler = new Multiplier(2)
Multiplier triple = new Multiplier(3)
println doubler.multiply(10)
println triple.multiply(10)
def multiply = { int times, int number ->
times * number
}
def doubler = multiply.curry(2)
def triple = multiply.curry(3)
println doubler(10)
println triple(10)
def numbers = [1, 2, 3, 4, 5, 6]
println numbers
.findAll { it % 2 == 0 }
.find { it > 2 }
To Streams API
def numbers = [1, 2, 3, 4, 5, 6]
println numbers
.findAll { it % 2 == 0 }
.find { it > 2 }
def numbers = [1, 2, 3, 4, 5, 6]
println numbers
.stream()
.filter { it % 2 == 0 }
.filter { it > 2 }
.findFirst()
.orElse(null)
interface CanSwim {
def swim()
}
class Fish implements CanSwim {
def swim() {
println "Fish Swimming"
}
}
class Person implements CanSwim {
def swim() {
println "Person Swimming"
}
}
To Dynamic Groovy
interface CanSwim {
def swim()
}
class Fish implements CanSwim {
def swim() {
println "Fish Swimming"
}
}
class Person implements CanSwim {
def swim() {
println "Person Swimming"
}
}
CanSwim swimmer = new Person() //new Fish()
swimmer.swim()
interface CanSwim {
def swim()
}
class Fish implements CanSwim {
def swim() {
println "Fish Swimming"
}
}
class Person implements CanSwim {
def swim() {
println "Person Swimming"
}
}
def swimmer = new Person() //new Fish()
swimmer.swim()
class Employee {
def employeeId
def firstName
def lastName
def dateOfBirth
def toSummaryString() {
"$employeeId -> $firstname"
}
}
class Employee {
def employeeId
def firstName
def lastName
def dateOfBirth
def toSummaryString() {
"$employeeId -> $firstname"
}
}
To Static Groovy
class Employee {
def employeeId
def firstName
def lastName
def dateOfBirth
def toSummaryString() {
"$employeeId -> $firstname"
}
}
Exception in thread "main" groovy.lang.MissingPropertyException:
No such property: firstname for class
@TypeChecked
class Employee {
def employeeId
def firstName
def lastName
def dateOfBirth
def toSummaryString() {
"$employeeId -> $firstname"
}
}
Error:(17, 30) Groovyc: [Static type checking] -
The variable [firstname] is undeclared.
@TypeChecked
class Employee {
def employeeId
def firstName
def lastName
def dateOfBirth
def toSummaryString() {
"$employeeId -> $firstname"
}
}
@TypeChecked
class Employee {
String employeeId
String firstName
String lastName
LocalDateTime dateOfBirth
def toSummaryString() {
"$employeeId -> $firstname"
}
}
TypeChecked
Vs
CompileStatic
class Greeter {
String message
def greet() {
message
}
}
@TypeChecked
def runTypeChecked(Greeter greeter) {
println greeter.greet()
}
@CompileStatic
def runCompileStatic(Greeter greeter) {
println greeter.greet()
}
def greeter = new Greeter(message: 'Good Morning')
greeter.metaClass.greet = { "Hello, ${delegate.message}" }
runTypeChecked(greeter)
runCompileStatic(greeter)
Hello, Good Morning
Good Morning
@Transactional
class MyService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
def m1() {}
def m2(){
m1()
}
}
Introduce Meta-programming
@Transactional
class MyService implements ApplicationContextAware {
ApplicationContext context
@Transactional(propagation = Propagation.REQUIRES_NEW)
def m1() {}
def m2() {
MyService service = context.getBean('myService')
service.m1()
}
@Override
void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
context = applicationContext
}
}
def grailsApplication
def init = { servletContext ->
injectSelfProxy()
}
private def injectSelfProxy(){
for (sc in grailsApplication.serviceClasses) {
String propertyName = sc.propertyName
sc.clazz.metaClass.getMyProxy = { ->
grailsApplication.mainContext
.getBean(propertyName)
}
}
}
@Transactional
class MyService {
ApplicationContext context
@Transactional(propagation = Propagation.REQUIRES_NEW)
def m1() {}
def m2() {
myProxy.m1()
}
}
Introduce Traits
class Product {
UUID uuid = UUID.randomUUID()
//other fields
}
class Order {
UUID uuid = UUID.randomUUID()
//other fields
}
class Product {
UUID uuid = UUID.randomUUID()
//other fields
}
class Order {
UUID uuid = UUID.randomUUID()
//other fields
}
trait BusinessObject {
}
class Product implements BusinessObject {
//other fields
}
class Order implements BusinessObject {
//other fields
}
trait BusinessObject {
UUID uuid = UUID.randomUUID()
}
class Technologies extends ArrayList {
def filterGr8() {
this.findAll { it.startsWith('Gr')}
}
}
Technologies list =
[‘Groovy', 'Grails', 'Gradle', 'Java'] as Technologies
println list
println list.filterGr8()
Replace Inheritance
with Delegation
class Technologies {
@Delegate
private List list
Technologies(List list) {
this.list = list
}
def filterGr8() {
list.findAll { it.startsWith('Gr') }
}
}
Thank You

Mais conteúdo relacionado

Mais procurados

Python Usage (5-minute-summary)
Python Usage (5-minute-summary)Python Usage (5-minute-summary)
Python Usage (5-minute-summary)Ohgyun Ahn
 
Pre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPaweł Dawczak
 
DATA STRUCTURE CLASS 12 COMPUTER SCIENCE
DATA STRUCTURE CLASS 12 COMPUTER SCIENCEDATA STRUCTURE CLASS 12 COMPUTER SCIENCE
DATA STRUCTURE CLASS 12 COMPUTER SCIENCEDev Chauhan
 
Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School ProgrammersSiva Arunachalam
 
Комплекс тоо цуврал хичээл-2
Комплекс тоо цуврал хичээл-2Комплекс тоо цуврал хичээл-2
Комплекс тоо цуврал хичээл-2Март
 
Python data structures
Python data structuresPython data structures
Python data structuresHarry Potter
 
Day 4 reviewwithchainandpart
Day 4  reviewwithchainandpartDay 4  reviewwithchainandpart
Day 4 reviewwithchainandpartjbianco9910
 
chap 2 Ex#1.1
chap 2 Ex#1.1chap 2 Ex#1.1
chap 2 Ex#1.1Ans Ali
 
10.5 more on language of functions x
10.5 more on language of functions x10.5 more on language of functions x
10.5 more on language of functions xmath260
 

Mais procurados (16)

Python Usage (5-minute-summary)
Python Usage (5-minute-summary)Python Usage (5-minute-summary)
Python Usage (5-minute-summary)
 
Pre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to Elixir
 
Python Regular Expressions
Python Regular ExpressionsPython Regular Expressions
Python Regular Expressions
 
Python lists
Python listsPython lists
Python lists
 
DATA STRUCTURE CLASS 12 COMPUTER SCIENCE
DATA STRUCTURE CLASS 12 COMPUTER SCIENCEDATA STRUCTURE CLASS 12 COMPUTER SCIENCE
DATA STRUCTURE CLASS 12 COMPUTER SCIENCE
 
Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School Programmers
 
Functions & graphs
Functions & graphsFunctions & graphs
Functions & graphs
 
Algebra 6
Algebra 6Algebra 6
Algebra 6
 
Комплекс тоо цуврал хичээл-2
Комплекс тоо цуврал хичээл-2Комплекс тоо цуврал хичээл-2
Комплекс тоо цуврал хичээл-2
 
Python data structures
Python data structuresPython data structures
Python data structures
 
Day 4 reviewwithchainandpart
Day 4  reviewwithchainandpartDay 4  reviewwithchainandpart
Day 4 reviewwithchainandpart
 
chap 2 Ex#1.1
chap 2 Ex#1.1chap 2 Ex#1.1
chap 2 Ex#1.1
 
Python collections
Python collectionsPython collections
Python collections
 
10.5 more on language of functions x
10.5 more on language of functions x10.5 more on language of functions x
10.5 more on language of functions x
 
Manual de sistemas
Manual de sistemasManual de sistemas
Manual de sistemas
 
LIST IN PYTHON
LIST IN PYTHONLIST IN PYTHON
LIST IN PYTHON
 

Semelhante a Groovy Refactoring Patterns

11 1. multi-dimensional array eng
11 1. multi-dimensional array eng11 1. multi-dimensional array eng
11 1. multi-dimensional array eng웅식 전
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingSergey Shishkin
 
Problem 1 Show the comparison of runtime of linear search and binar.pdf
Problem 1 Show the comparison of runtime of linear search and binar.pdfProblem 1 Show the comparison of runtime of linear search and binar.pdf
Problem 1 Show the comparison of runtime of linear search and binar.pdfebrahimbadushata00
 
Gentle Introduction to Functional Programming
Gentle Introduction to Functional ProgrammingGentle Introduction to Functional Programming
Gentle Introduction to Functional ProgrammingSaurabh Singh
 
Raspberry Pi - Lecture 5 Python for Raspberry Pi
Raspberry Pi - Lecture 5 Python for Raspberry PiRaspberry Pi - Lecture 5 Python for Raspberry Pi
Raspberry Pi - Lecture 5 Python for Raspberry PiMohamed Abdallah
 
Mixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented languageMixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented languageMark Needham
 
Swift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdfSwift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdfJkPoppy
 
C++ Course - Lesson 2
C++ Course - Lesson 2C++ Course - Lesson 2
C++ Course - Lesson 2Mohamed Ahmed
 
Computation of Semi-Magic Squares Generated by Serpentine Matrices
Computation of Semi-Magic Squares Generated by Serpentine MatricesComputation of Semi-Magic Squares Generated by Serpentine Matrices
Computation of Semi-Magic Squares Generated by Serpentine MatricesLossian Barbosa Bacelar Miranda
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadiesAlicia Pérez
 
Basic operations by novi reandy sasmita
Basic operations by novi reandy sasmitaBasic operations by novi reandy sasmita
Basic operations by novi reandy sasmitabeasiswa
 
Step 1 Implement the getSortedRunLength() methodImplement the get.pdf
Step 1 Implement the getSortedRunLength() methodImplement the get.pdfStep 1 Implement the getSortedRunLength() methodImplement the get.pdf
Step 1 Implement the getSortedRunLength() methodImplement the get.pdfaloeplusint
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.jstimourian
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersTikal Knowledge
 

Semelhante a Groovy Refactoring Patterns (20)

bobok
bobokbobok
bobok
 
11 1. multi-dimensional array eng
11 1. multi-dimensional array eng11 1. multi-dimensional array eng
11 1. multi-dimensional array eng
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional Programming
 
Problem 1 Show the comparison of runtime of linear search and binar.pdf
Problem 1 Show the comparison of runtime of linear search and binar.pdfProblem 1 Show the comparison of runtime of linear search and binar.pdf
Problem 1 Show the comparison of runtime of linear search and binar.pdf
 
Gentle Introduction to Functional Programming
Gentle Introduction to Functional ProgrammingGentle Introduction to Functional Programming
Gentle Introduction to Functional Programming
 
Raspberry Pi - Lecture 5 Python for Raspberry Pi
Raspberry Pi - Lecture 5 Python for Raspberry PiRaspberry Pi - Lecture 5 Python for Raspberry Pi
Raspberry Pi - Lecture 5 Python for Raspberry Pi
 
07. Arrays
07. Arrays07. Arrays
07. Arrays
 
Python.pdf
Python.pdfPython.pdf
Python.pdf
 
Arrays
ArraysArrays
Arrays
 
Mixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented languageMixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented language
 
Swift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdfSwift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdf
 
C++ Course - Lesson 2
C++ Course - Lesson 2C++ Course - Lesson 2
C++ Course - Lesson 2
 
Computation of Semi-Magic Squares Generated by Serpentine Matrices
Computation of Semi-Magic Squares Generated by Serpentine MatricesComputation of Semi-Magic Squares Generated by Serpentine Matrices
Computation of Semi-Magic Squares Generated by Serpentine Matrices
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
 
Basic operations by novi reandy sasmita
Basic operations by novi reandy sasmitaBasic operations by novi reandy sasmita
Basic operations by novi reandy sasmita
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
Step 1 Implement the getSortedRunLength() methodImplement the get.pdf
Step 1 Implement the getSortedRunLength() methodImplement the get.pdfStep 1 Implement the getSortedRunLength() methodImplement the get.pdf
Step 1 Implement the getSortedRunLength() methodImplement the get.pdf
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 

Mais de Naresha K

The Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockThe Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockNaresha K
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveNaresha K
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersNaresha K
 
Implementing Resilience with Micronaut
Implementing Resilience with MicronautImplementing Resilience with Micronaut
Implementing Resilience with MicronautNaresha K
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersNaresha K
 
Favouring Composition - The Groovy Way
Favouring Composition - The Groovy WayFavouring Composition - The Groovy Way
Favouring Composition - The Groovy WayNaresha K
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesNaresha K
 
What's in Groovy for Functional Programming
What's in Groovy for Functional ProgrammingWhat's in Groovy for Functional Programming
What's in Groovy for Functional ProgrammingNaresha K
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Naresha K
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Naresha K
 
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...Naresha K
 
Implementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautImplementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautNaresha K
 
Groovy - Why and Where?
Groovy  - Why and Where?Groovy  - Why and Where?
Groovy - Why and Where?Naresha K
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaNaresha K
 
Implementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautImplementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautNaresha K
 
Effective Java with Groovy
Effective Java with GroovyEffective Java with Groovy
Effective Java with GroovyNaresha K
 
Evolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveEvolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveNaresha K
 
Effective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesEffective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesNaresha K
 
Beyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaBeyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaNaresha K
 
GORM - The polyglot data access toolkit
GORM - The polyglot data access toolkitGORM - The polyglot data access toolkit
GORM - The polyglot data access toolkitNaresha K
 

Mais de Naresha K (20)

The Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockThe Groovy Way of Testing with Spock
The Groovy Way of Testing with Spock
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain Effective
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Implementing Resilience with Micronaut
Implementing Resilience with MicronautImplementing Resilience with Micronaut
Implementing Resilience with Micronaut
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Favouring Composition - The Groovy Way
Favouring Composition - The Groovy WayFavouring Composition - The Groovy Way
Favouring Composition - The Groovy Way
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good Practices
 
What's in Groovy for Functional Programming
What's in Groovy for Functional ProgrammingWhat's in Groovy for Functional Programming
What's in Groovy for Functional Programming
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
 
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
 
Implementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautImplementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with Micronaut
 
Groovy - Why and Where?
Groovy  - Why and Where?Groovy  - Why and Where?
Groovy - Why and Where?
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS Lambda
 
Implementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautImplementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with Micronaut
 
Effective Java with Groovy
Effective Java with GroovyEffective Java with Groovy
Effective Java with Groovy
 
Evolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveEvolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and Effective
 
Effective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesEffective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good Practices
 
Beyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaBeyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in Java
 
GORM - The polyglot data access toolkit
GORM - The polyglot data access toolkitGORM - The polyglot data access toolkit
GORM - The polyglot data access toolkit
 

Último

Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in sowetomasabamasaba
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 

Último (20)

Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 

Groovy Refactoring Patterns

  • 2. About me Developer, Coach, Consultant Founder & Organiser Bangalore Groovy User Group
  • 4. noun: a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behaviour verb: to restructure software by applying a series of refactorings without changing its observable behaviour. Refactoring https://refactoring.com/
  • 7. A code smell is a surface indication that usually corresponds to a deeper problem in the system. The term was first coined by Kent Beck while helping me with my Refactoring book. ~ Martin Fowler https://martinfowler.com/bliki/CodeSmell.html
  • 8. { Code Smells } Long Methods Duplicated Code Large Class Long Param List Primitive Obsession Data Class Inappropriate Intimacy
  • 9. int calculateM1(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue + 1 } int calculateM2(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue * 2 }
  • 10. int calculateM1(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue + 1 } int calculateM2(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue * 2 } Duplicate Code Reinventing the wheel
  • 11. int calculateM1(int value1, int value2, int value3) { Math.max(value1, Math.max(value2, value3)) + 1 } int calculateM2(int value1, int value2, int value3) { Math.max(value1, Math.max(value2, value3)) * 2 }
  • 12.
  • 13. int calculateM1(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue + 1 } int calculateM2(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue * 2 }
  • 14. int calculateM1(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue + 1 } int calculateM1(int value1, int value2, int value3) { int maxValue = max(value1, value2, value3) maxValue + 1 } private int max(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue } Extract Method
  • 15. int calculateM1(int value1, int value2, int value3) { int maxValue = max(value1, value2, value3) maxValue + 1 } private int max(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue } int calculateM2(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue * 2 }
  • 16. int calculateM1(int value1, int value2, int value3) { int maxValue = max(value1, value2, value3) maxValue + 1 } private int max(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue } int calculateM2(int value1, int value2, int value3) { int maxValue = max(value1, value2, value3) maxValue * 2 }
  • 17. private int max(int value1, int value2, int value3) { int maxValue if (value1 > value2 && value1 > value3) { maxValue = value1 } else if (value2 > value3) { maxValue = value2 } else { maxValue = value3 } maxValue } private int max(int value1, int value2, int value3) { Math.max(value1, Math.max(value2, value3)) }
  • 18. private int max(int value1, int value2, int value3) { Math.max(value1, Math.max(value2, value3)) } int calculateM1(int value1, int value2, int value3) { int maxValue = max(value1, value2, value3) maxValue + 1 } int calculateM2(int value1, int value2, int value3) { int maxValue = max(value1, value2, value3) maxValue * 2 }
  • 19. private int max(int value1, int value2, int value3) { Math.max(value1, Math.max(value2, value3)) } int calculateM1(int value1, int value2, int value3) { int maxValue = Math.max(value1, Math.max(value2, value3)) maxValue + 1 } int calculateM2(int value1, int value2, int value3) { int maxValue = Math.max(value1, Math.max(value2, value3)) maxValue * 2 } Inline Method
  • 20. int calculateM1(int value1, int value2, int value3) { int maxValue = Math.max(value1, Math.max(value2, value3)) maxValue + 1 } int calculateM2(int value1, int value2, int value3) { int maxValue = Math.max(value1, Math.max(value2, value3)) maxValue * 2 } int calculateM1(int value1, int value2, int value3) { Math.max(value1, Math.max(value2, value3)) + 1 } int calculateM2(int value1, int value2, int value3) { Math.max(value1, Math.max(value2, value3)) * 2 } Inline Variable
  • 21. Importance of small steps in refactoring
  • 22.
  • 23. List<Integer> numbers = [1, 2, 3, 4, 5] for(number in numbers) { println number }
  • 25. List<Integer> numbers = [1, 2, 3, 4, 5] for(number in numbers) { println number } List<Integer> numbers = [1, 2, 3, 4, 5] numbers.forEach { println it } List<Integer> numbers = [1, 2, 3, 4, 5] numbers.forEach(System.out.&println)
  • 26.
  • 28. def numbers = [1, 2, 3, 4, 5] for(number in numbers) { println number } def numbers = [1, 2, 3, 4, 5] numbers.each { println it }
  • 29. def evenNumbers = [] numbers.each { number -> if (number % 2 == 0) { evenNumbers << number } } def evenNumbers = numbers .findAll { it % 2 == 0}
  • 30. def sum = 0 numbers.each { sum += it } def sum = numbers.inject(0, { result, number -> result + number } )
  • 31. List<Integer> numbers = [1, 2, 3, 4, 5] def result = [:] numbers.forEach { number -> result[number] = number * number } List<Integer> numbers = [1, 2, 3, 4, 5] def result = numbers.collectEntries { [it, it * it] }
  • 32.
  • 33. List<Integer> numbers = [1, 2, 3, 4, 5] def evenNumbers = numbers.findAll { it % 2 == 0}
  • 35. List<Integer> numbers = [1, 2, 3, 4, 5] def evenNumbers = numbers.findAll { it % 2 == 0} List<Integer> numbers = [1, 2, 3, 4, 5] def evenNumbers = numbers.findAll({ it % 2 == 0 }) List<Integer> numbers = [1, 2, 3, 4, 5] def isEven = { it % 2 == 0 } def evenNumbers = numbers.findAll(isEven)
  • 37. List<Integer> numbers = [1, 2, 3, 4, 5] def isEven = { it % 2 == 0 } def evenNumbers = numbers.findAll(isEven) List<Integer> numbers = [1, 2, 3, 4, 5] def evenNumbers = numbers.findAll { it % 2 == 0}
  • 38.
  • 39. def numbers = [1, 2, 3, 4, 5] def sumOfSuqaresOfEvenNumbers = 0 numbers.forEach { number -> if(number % 2 == 0 ){ sumOfSuqaresOfEvenNumbers += number * number } }
  • 41. def numbers = [1, 2, 3, 4, 5] def sumOfSuqaresOfEvenNumbers = 0 numbers.forEach { number -> if(number % 2 == 0 ){ sumOfSuqaresOfEvenNumbers += number * number } } def sumOfSuqaresOfEvenNumbers = numbers .findAll { it % 2 == 0 } .collect { it * it } .sum()
  • 42.
  • 43. def numbers = [1, 2, 3, 4, 5] def sumOfSuqaresOfEvenNumbers = 0 numbers.forEach { number -> if(number % 2 == 0 ){ sumOfSuqaresOfEvenNumbers += number * number } } def square = { it * it } def sumOfSuqaresOfEvenNumbers = 0 numbers.forEach { number -> if(number % 2 == 0 ){ sumOfSuqaresOfEvenNumbers += square(number) } }
  • 44. def square = { it * it } def sumOfSuqaresOfEvenNumbers = 0 numbers.forEach { number -> if(number % 2 == 0 ){ sumOfSuqaresOfEvenNumbers += square(number) } } def sumOfSuqaresOfEvenNumbers = 0 def evenNumbers = numbers.findAll { it % 2 == 0} evenNumbers.forEach { number -> sumOfSuqaresOfEvenNumbers += square(number) }
  • 45. def sumOfSuqaresOfEvenNumbers = 0 def evenNumbers = numbers.findAll { it % 2 == 0} evenNumbers.forEach { number -> sumOfSuqaresOfEvenNumbers += square(number) } def sumOfSuqaresOfEvenNumbers = 0 def evenNumbers = numbers.findAll { it % 2 == 0} def squaresOfEvenNumbers = evenNumbers.collect(square) squaresOfEvenNumbers.forEach { number -> sumOfSuqaresOfEvenNumbers += number }
  • 46. def square = { it * it } def evenNumbers = numbers.findAll { it % 2 == 0 } def squaresOfEvenNumbers = evenNumbers .collect ( square ) def sumOfSuqaresOfEvenNumbers = squaresOfEvenNumbers.sum() def sumOfSuqaresOfEvenNumbers = 0 def evenNumbers = numbers.findAll { it % 2 == 0} def squaresOfEvenNumbers = evenNumbers.collect(square) squaresOfEvenNumbers.forEach { number -> sumOfSuqaresOfEvenNumbers += number }
  • 47. def square = { it * it } def evenNumbers = numbers.findAll { it % 2 == 0 } def squaresOfEvenNumbers = evenNumbers .collect ( square ) def sumOfSuqaresOfEvenNumbers = squaresOfEvenNumbers.sum() def sumOfSuqaresOfEvenNumbers = numbers .findAll { it % 2 == 0 } .collect (square) .sum() Inline
  • 48.
  • 49. class Multiplier { private final int times Multiplier(int times) { this.times = times } int multiply(int number) { times * number } } Multiplier doubler = new Multiplier(2) Multiplier triple = new Multiplier(3) println doubler.multiply(10) println triple.multiply(10)
  • 50. def multiply = { int times, int number -> times * number } def doubler = multiply.curry(2) def triple = multiply.curry(3) println doubler(10) println triple(10)
  • 51.
  • 52. def numbers = [1, 2, 3, 4, 5, 6] println numbers .findAll { it % 2 == 0 } .find { it > 2 }
  • 54. def numbers = [1, 2, 3, 4, 5, 6] println numbers .findAll { it % 2 == 0 } .find { it > 2 } def numbers = [1, 2, 3, 4, 5, 6] println numbers .stream() .filter { it % 2 == 0 } .filter { it > 2 } .findFirst() .orElse(null)
  • 55.
  • 56. interface CanSwim { def swim() } class Fish implements CanSwim { def swim() { println "Fish Swimming" } } class Person implements CanSwim { def swim() { println "Person Swimming" } }
  • 58. interface CanSwim { def swim() } class Fish implements CanSwim { def swim() { println "Fish Swimming" } } class Person implements CanSwim { def swim() { println "Person Swimming" } } CanSwim swimmer = new Person() //new Fish() swimmer.swim()
  • 59. interface CanSwim { def swim() } class Fish implements CanSwim { def swim() { println "Fish Swimming" } } class Person implements CanSwim { def swim() { println "Person Swimming" } } def swimmer = new Person() //new Fish() swimmer.swim()
  • 60.
  • 61. class Employee { def employeeId def firstName def lastName def dateOfBirth def toSummaryString() { "$employeeId -> $firstname" } }
  • 62. class Employee { def employeeId def firstName def lastName def dateOfBirth def toSummaryString() { "$employeeId -> $firstname" } }
  • 64. class Employee { def employeeId def firstName def lastName def dateOfBirth def toSummaryString() { "$employeeId -> $firstname" } } Exception in thread "main" groovy.lang.MissingPropertyException: No such property: firstname for class
  • 65. @TypeChecked class Employee { def employeeId def firstName def lastName def dateOfBirth def toSummaryString() { "$employeeId -> $firstname" } } Error:(17, 30) Groovyc: [Static type checking] - The variable [firstname] is undeclared.
  • 66. @TypeChecked class Employee { def employeeId def firstName def lastName def dateOfBirth def toSummaryString() { "$employeeId -> $firstname" } } @TypeChecked class Employee { String employeeId String firstName String lastName LocalDateTime dateOfBirth def toSummaryString() { "$employeeId -> $firstname" } }
  • 68. class Greeter { String message def greet() { message } } @TypeChecked def runTypeChecked(Greeter greeter) { println greeter.greet() } @CompileStatic def runCompileStatic(Greeter greeter) { println greeter.greet() }
  • 69. def greeter = new Greeter(message: 'Good Morning') greeter.metaClass.greet = { "Hello, ${delegate.message}" } runTypeChecked(greeter) runCompileStatic(greeter) Hello, Good Morning Good Morning
  • 70. @Transactional class MyService { @Transactional(propagation = Propagation.REQUIRES_NEW) def m1() {} def m2(){ m1() } }
  • 72. @Transactional class MyService implements ApplicationContextAware { ApplicationContext context @Transactional(propagation = Propagation.REQUIRES_NEW) def m1() {} def m2() { MyService service = context.getBean('myService') service.m1() } @Override void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext } }
  • 73. def grailsApplication def init = { servletContext -> injectSelfProxy() } private def injectSelfProxy(){ for (sc in grailsApplication.serviceClasses) { String propertyName = sc.propertyName sc.clazz.metaClass.getMyProxy = { -> grailsApplication.mainContext .getBean(propertyName) } } }
  • 74. @Transactional class MyService { ApplicationContext context @Transactional(propagation = Propagation.REQUIRES_NEW) def m1() {} def m2() { myProxy.m1() } }
  • 76. class Product { UUID uuid = UUID.randomUUID() //other fields } class Order { UUID uuid = UUID.randomUUID() //other fields }
  • 77. class Product { UUID uuid = UUID.randomUUID() //other fields } class Order { UUID uuid = UUID.randomUUID() //other fields } trait BusinessObject { }
  • 78. class Product implements BusinessObject { //other fields } class Order implements BusinessObject { //other fields } trait BusinessObject { UUID uuid = UUID.randomUUID() }
  • 79.
  • 80. class Technologies extends ArrayList { def filterGr8() { this.findAll { it.startsWith('Gr')} } } Technologies list = [‘Groovy', 'Grails', 'Gradle', 'Java'] as Technologies println list println list.filterGr8()
  • 82. class Technologies { @Delegate private List list Technologies(List list) { this.list = list } def filterGr8() { list.findAll { it.startsWith('Gr') } } }