SlideShare une entreprise Scribd logo
1  sur  83
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

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
 

Tendances (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
 

Similaire à 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
 

Similaire à 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
 

Plus 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
 

Plus 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
 

Dernier

Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
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
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxalwaysnagaraju26
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
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
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 

Dernier (20)

Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
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...
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
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
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

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') } } }