Download presentation
Presentation is loading. Please wait.
1
Refactoring hacked Sebastian Malaca
2
Who am I? Fanatic of the OOP and the Code’s Quality Blogger Speaker
Trainer and consultant Software Developer at Luxoft @SebastianMalaca letstalkaboutjava.blogspot.com letstalkaboutjava.blogspot.com
3
What's in the Menu? What is Refactoring? Is it worth the effort?
What you should know about Refactoring? How? letstalkaboutjava.blogspot.com
4
What is Refactoring? letstalkaboutjava.blogspot.com
5
SMALL CHANGES What is Refactoring?
letstalkaboutjava.blogspot.com
6
NO CHANGES!!! SMALL CHANGES What is Refactoring?
letstalkaboutjava.blogspot.com
7
READABILITY SMALL CHANGES NO CHANGES!!! What is Refactoring?
letstalkaboutjava.blogspot.com
8
Is it worth the effort? letstalkaboutjava.blogspot.com
9
Is it worth the effort? It's expensive -> Small changes -> Habit
letstalkaboutjava.blogspot.com
10
Is it worth the effort? It's NOT expensive
Only for big projects -> Success -> Long life letstalkaboutjava.blogspot.com
11
Is it worth the effort? It's NOT expensive NOT only for big projects
Must have in big projects -> Come and go -> no author -> readability letstalkaboutjava.blogspot.com
12
Refactoring vs. Redesign
13
Refactoring vs. Redesign
Readability and Understanding Atomic changes Class as a starting point Ad hoc Improvements and Extensions Complex changes Dependencies Planning letstalkaboutjava.blogspot.com
14
Stay safe!
15
Stay safe! No tests, no fun!
letstalkaboutjava.blogspot.com
16
Stay safe! No tests, no fun! Experimentation or Professionalism?
letstalkaboutjava.blogspot.com
17
Stay safe! No tests, no fun! Experimentation or Professionalism?
Doubts vs. Certainty letstalkaboutjava.blogspot.com
18
You have to know when to stop!
19
You have to know when to stop
Refactoring is fun letstalkaboutjava.blogspot.com
20
You have to know when to stop
Refactoring is fun Refactoring – neverending story letstalkaboutjava.blogspot.com
21
You have to know when to stop
Refactoring is fun Refactoring – neverending story Boundaries and Values letstalkaboutjava.blogspot.com
22
You have to know when to stop
Refactoring is fun Refactoring – neverending story Boundaries and Values Perfection! letstalkaboutjava.blogspot.com
23
You have to know when to stop
Refactoring is fun Refactoring – neverending story Boundaries and Values Perfection! Software with the users vs. Ideal software letstalkaboutjava.blogspot.com
24
You have to know when to stop
Refactoring is fun Refactoring – neverending story Boundaries and Values Perfection! Software with the users vs. Ideal software letstalkaboutjava.blogspot.com
25
www.luxoft.com, @SebastianMalaca, letstalkaboutjava.blogspot.com
26
It’s worth to know patterns
27
It’s worth to know patterns
letstalkaboutjava.blogspot.com
28
Gimme the name! letstalkaboutjava.blogspot.com
29
Let's take a look at the code!
30
There’s only a small condition…
31
Less dependencies private TestsRepository testsRepository; private CodeBaseRepository codeBaseRepository; public void apply(ClassCode code, Developer developer) { if (codeBaseRepository.contains(code) && testsRepository.testsExistFor(code)) { startRefactoringOf(code, developer); } } letstalkaboutjava.blogspot.com
32
Less dependencies private TestsRepository testsRepository; private CodeBaseRepository codeBaseRepository; public void apply(ClassCode code, Developer developer) { if (codeBaseRepository.contains(code) && testsRepository.testsExistFor(code)) { startRefactoringOf(code, developer); } } private RefactoringPossiblePredicate refactoringPossiblePredicate; public void apply(ClassCode code) { if (refactoringPossiblePredicate.apply(code)) { startRefactoringOf(code, developer); } } letstalkaboutjava.blogspot.com
33
The size matters! private TestsRepository testsRepository; public void apply(ClassCode code, Developer developer) { if (testsRepository.testsExistFor(code) && developer.canModify(code) && (code.isComplex() || code.isUnreadable())) { startRefactoringOf(code); } } letstalkaboutjava.blogspot.com
34
The size matters! When object knows…
private TestsRepository testsRepository; public void apply(ClassCode code, Developer developer) { if (testsRepository.testsExistFor(code) && developer.canModify(code) && (code.isComplex() || code.isUnreadable())) { startRefactoringOf(code); } } When object knows… private TestsRepository testsRepository; public void apply(ClassCode code, Developer developer) { if (testsRepository.testsExistFor(code) && developer.canModify(code) && code.canBeImproved()) { startRefactoringOf(code); } } letstalkaboutjava.blogspot.com
35
The size matters! Single Responsibility Principle
private TestsRepository testsRepository; public void apply(ClassCode code, Developer developer) { if (testsRepository.testsExistFor(code) && developer.canModify(code) && (code.isComplex() || code.isUnreadable())) { startRefactoringOf(code); } } private TestsRepository testsRepository; public void apply(ClassCode code, Developer developer) { if (testsRepository.testsExistFor(code) && developer.canModify(code) && code.canBeImproved()) { startRefactoringOf(code); } } private CanStartRefactoringPredicate canStartRefactoringPredicate; public void apply(ClassCode code, Developer developer) { if (canStartRefactoringPredicate.apply(code, developer)) { startRefactoringOf(code); } } Single Responsibility Principle letstalkaboutjava.blogspot.com
36
Or And?
37
Or if (code.isComplexOrUnreadable()) { doRefactoring(code); }
letstalkaboutjava.blogspot.com
38
Or if (code.isComplexOrUnreadable()) { doRefactoring(code); }
if (code.canBeImproved()) { doRefactoring(code); } letstalkaboutjava.blogspot.com
39
And if (isRefactoringPossibleAndJustifiedPredicate.apply(code, developer)) { doRefactoring(code); } letstalkaboutjava.blogspot.com
40
And if (isRefactoringPossibleAndJustifiedPredicate.apply(code, developer)) { doRefactoring(code); } if (canStartRefactoringPredicate.apply(code, developer)) { doRefactoring(code); } letstalkaboutjava.blogspot.com
41
Method’s name makes a difference
42
Method’s name makes a difference
refactoring.setState(IN_PROGRESS); refactoring.setState(VERIFIED); refactoring.setState(DONE); letstalkaboutjava.blogspot.com
43
Method’s name makes a difference
refactoring.setState(IN_PROGRESS); refactoring.setState(VERIFIED); refactoring.setState(DONE); refactoring.start(); refactoring.accepted(); refactoring.applied(); letstalkaboutjava.blogspot.com
44
Don’t show too much
45
Law of Demeter public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getMethodByName(refactoring.getScope()).getCondition(); RefactoringApplier.applyRefactoringFor(condition, refactoring); } letstalkaboutjava.blogspot.com
46
Law of Demeter public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getMethodByName(refactoring.getScope()).getCondition(); RefactoringApplier.applyRefactoringFor(condition, refactoring); } public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getConditionOf(refactoring.getScope()); RefactoringApplier.applyRefactoringFor(condition, refactoring); } letstalkaboutjava.blogspot.com
47
Tell, don’t Ask public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getMethodByName(refactoring.getScope()).getCondition(); RefactoringApplier.applyRefactoringFor(condition, refactoring); } public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getConditionOf(refactoring.getScope()); RefactoringApplier.applyRefactoringFor(condition, refactoring); } letstalkaboutjava.blogspot.com
48
Tell, don’t Ask public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getMethodByName(refactoring.getScope()).getCondition(); RefactoringApplier.applyRefactoringFor(condition, refactoring); } public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getConditionOf(refactoring.getScope()); RefactoringApplier.applyRefactoringFor(condition, refactoring); } public void apply(ClassCode code, Refactoring refactoring) { code.apply(refactoring); } letstalkaboutjava.blogspot.com
49
Asking many objects… Tell, don’t Ask
public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getMethodByName(refactoring.getScope()).getCondition(); RefactoringApplier.applyRefactoringFor(condition, refactoring); } Asking many objects… public void apply(ClassCode code, Refactoring refactoring) { Condition condition = code.getConditionOf(refactoring.getScope()); RefactoringApplier.applyRefactoringFor(condition, refactoring); } public void apply(ClassCode code, Refactoring refactoring) { code.apply(refactoring); } letstalkaboutjava.blogspot.com
50
Too much is… too much
51
Too much is… too much public class History { public void store(
Author author, RefactoringType type, Scope scope, RefactoringJustification justification, Date today) { // some code } letstalkaboutjava.blogspot.com
52
Too much is… too much public class History { public void store(
Author author, RefactoringType type, Scope scope, RefactoringJustification justification, Date today) { // some code } public class History { public void store(CodeDelta delta) { // some code } letstalkaboutjava.blogspot.com
53
Input & Output
54
Input & Output public void verify(Change change) { Refactoring refactoring = change.getRefactoring(); ClassCode affectedCode = change.getAffectedCode(); CodeUnit codeUnit = codeBaseRepository.findCodeUnitFor(affectedCode); codeUnit.applyRefactoringFor(affectedCode, refactoring); testsExecutor.runFor(codeUnit); } letstalkaboutjava.blogspot.com
55
Input & Output public void verify(Change change) { Refactoring refactoring = change.getRefactoring(); ClassCode affectedCode = change.getAffectedCode(); CodeUnit codeUnit = codeBaseRepository.findCodeUnitFor(affectedCode); codeUnit.applyRefactoringFor(affectedCode, refactoring); testsExecutor.runFor(codeUnit); } public void verify(Change change) { ClassCode affectedCode = change.getAffectedCode(); CodeUnit codeUnit = codeBaseRepository.findCodeUnitFor(affectedCode); codeUnit.apply(change); testsExecutor.runFor(codeUnit); } letstalkaboutjava.blogspot.com
56
(not so) easy choice
57
(not so) easy choice public void triggerRefactoringProcessing(Refactoring refactoring){ switch (refactoring.state()) { case DEFINED: moveToInProgressState(refactoring); break; case IN_PROGRESS: createChangeFor(refactoring); break; case TO_VERIFY: verifyChangeFor(refactoring); break; case VERIFIED: applyChangeFrom(refactoring); break; } } letstalkaboutjava.blogspot.com
58
(not so) easy choice public void triggerRefactoringProcessing(Refactoring refactoring){ switch (refactoring.state()) { case DEFINED: moveToInProgressState(refactoring); break; case IN_PROGRESS: createChangeFor(refactoring); break; case TO_VERIFY: verifyChangeFor(refactoring); break; case VERIFIED: applyChangeFrom(refactoring); break; } } private Map<RefactoringState, RefactoringTriggerStrategy> strategies; public RefactoringTrigger(Map<RefactoringState, RefactoringTriggerStrategy> strategies) { this.strategies = strategies; } public void triggerRefactoringProcessing(Refactoring refactoring){ strategies.get(refactoring.state()).triggerFor(refactoring); } letstalkaboutjava.blogspot.com
59
State Pattern maybe? (not so) easy choice
public void triggerRefactoringProcessing(Refactoring refactoring){ switch (refactoring.state()) { case DEFINED: moveToInProgressState(refactoring); break; case IN_PROGRESS: createChangeFor(refactoring); break; case TO_VERIFY: verifyChangeFor(refactoring); break; case VERIFIED: applyChangeFrom(refactoring); break; } } State Pattern maybe? private Map<RefactoringState, RefactoringTriggerStrategy> strategies; public RefactoringTrigger(Map<RefactoringState, RefactoringTriggerStrategy> strategies) { this.strategies = strategies; } public void triggerRefactoringProcessing(Refactoring refactoring){ strategies.get(refactoring.state()).triggerFor(refactoring); } letstalkaboutjava.blogspot.com
60
When you want to know too much…
61
When you want to know too much…
public void triggerProcessingChangeOf(Code code, Change change) { if (change instanceof Refactoring) { processRefactoring(code, (Refactoring) change); } else if (change instanceof Improvement) { processImprovement(code, (Improvement) change); } else if (change instanceof Growth) { processGrowth(code, (Growth) change); } else { throw new UnsuportedChangeException(); } }
62
When you want to know too much…
public void triggerProcessingChangeOf(Code code, Change change) { if (change instanceof Refactoring) { processRefactoring(code, (Refactoring) change); } else if (change instanceof Improvement) { processImprovement(code, (Improvement) change); } else if (change instanceof Growth) { processGrowth(code, (Growth) change); } else { throw new UnsuportedChangeException(); } }
63
When you want to know too much…
public void triggerProcessingChangeOf(Code code, Change change) { if (change instanceof Refactoring) { processRefactoring(code, (Refactoring) change); } else if (change instanceof Improvement) { processImprovement(code, (Improvement) change); } else if (change instanceof Growth) { processGrowth(code, (Growth) change); } else { throw new UnsuportedChangeException(); } }
64
When you want to know too much…
public void triggerProcessingChangeOf(Code code, Change change) { if (change instanceof Refactoring) { processRefactoring(code, (Refactoring) change); } else if (change instanceof Improvement) { processImprovement(code, (Improvement) change); } else if (change instanceof Growth) { processGrowth(code, (Growth) change); } else { throw new UnsuportedChangeException(); } } public void triggerProcessingChangeOf(Code code, Change change) { change.accept(new ChangeProcessor(code)); }
65
When you want to know too much…
public void triggerProcessingChangeOf(Code code, Change change) { change.accept(new ChangeProcessor(code)); } public interface Change { void accept(Visitator visitator); } public interface Visitator { void accept(Refactoring refactoring); void accept(Improvement improvement); void accept(Growth growth); }
66
When you want to know too much…
public void triggerProcessingChangeOf(Code code, Change change) { change.accept(new ChangeProcessor(code)); } public interface Change { void accept(Visitator visitator); } public interface Visitator { void accept(Refactoring refactoring); void accept(Improvement improvement); void accept(Growth growth); } public class ChangeProcessor implements Visitator { @Override public void accept(Refactoring refactoring) { // some code } @Override public void accept(Improvement improvement) { // some code } @Override public void accept(Growth growth) { // some code }
67
Far too much…
68
Far too much… public void process(Refactoring refactoring) { applyToCode(refactoring); createPullRequestWith(refactoring); doCodeReviewOf(refactoring); mergeToTheMaster(refactoring); }
69
Far too much… public void process(Refactoring refactoring) { applyToCode(refactoring); createPullRequestWith(refactoring); doCodeReviewOf(refactoring); mergeToTheMaster(refactoring); }
70
Far too much… public void process(Refactoring refactoring) { applyToCode(refactoring); createPullRequestWith(refactoring); doCodeReviewOf(refactoring); mergeToTheMaster(refactoring); } public interface RefactoringProcessor { void process(Refactoring refactoring); }
71
Far too much… public void process(Refactoring refactoring) { applyToCode(refactoring); createPullRequestWith(refactoring); doCodeReviewOf(refactoring); mergeToTheMaster(refactoring); } public interface RefactoringProcessor { void process(Refactoring refactoring); } public class CodeRefactoringProcessor implements RefactoringProcessor { @Override public void process(Refactoring refactoring) { applyToCode(refactoring); }
72
Far too much… public void process(Refactoring refactoring) { applyToCode(refactoring); createPullRequestWith(refactoring); doCodeReviewOf(refactoring); mergeToTheMaster(refactoring); } public interface RefactoringProcessor { void process(Refactoring refactoring); } public class CodeRefactoringProcessor implements RefactoringProcessor { @Override public void process(Refactoring refactoring) { applyToCode(refactoring); } public class PullRequestProcessor implements RefactoringProcessor { private final RefactoringProcessor processor; @Override public void process(Refactoring refactoring) { processor.process(refactoring); createPullRequestWith(refactoring); }
73
TL; DR
74
TL; DR Introduce private methods
Extract parts of the code organized around dependencies Conditions Switches Single Responsibility Principle letstalkaboutjava.blogspot.com
75
What was served?
76
What was served? What is Refactoring? Small changes No changes!!!
Readability letstalkaboutjava.blogspot.com
77
What was served? What is Refactoring? Is it worth the effort?
It's not expensive It's for any kind of project letstalkaboutjava.blogspot.com
78
What was served? What is Refactoring? Is it worth the effort?
What you should know about Refactoring? Refactoring vs. Redesign Stay safe! You have to know when to stop! letstalkaboutjava.blogspot.com
79
What was served? What is Refactoring? Is it worth the effort?
What you should know about Refactoring? How? letstalkaboutjava.blogspot.com
80
Always leave the campground cleaner than you found it.
Boy Scouts Rule letstalkaboutjava.blogspot.com
81
www.luxoft.com, @SebastianMalaca, letstalkaboutjava.blogspot.com
82
www.luxoft.com, @SebastianMalaca, letstalkaboutjava.blogspot.com
83
www.luxoft.com, @SebastianMalaca, letstalkaboutjava.blogspot.com
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.