VictorRentea.ro
21
victor.rentea@gmail.com ♦ ♦ @victorrentea ♦ VictorRentea.ro
Victor Rentea
VictorRentea.ro
Recorded Talks, Blog, Video Courses, ...
Independent Trainer
Founder of
Bucharest Software Craftsmanship Community
Java Champion
❤️ Simple Design, Refactoring, Unit Testing ❤️
Technical Training
500 days
(200+ online)
2000 devs
8 years 50+ companies
Reach out
to me:
Hibernate
Spring Func Prog
Java Performance
Reactive Prog
Design Patterns
Pragmatic DDD
Clean Code
Refactoring
Unit Testing
TDD
any
lang
@victorrentea
Intense
More: VictorRentea.ro
Workshops: victorrentea.teachable.com
24
CODE
25 © VictorRentea.ro
a training by
Refactoring
What must we do every single day?
What’s that?
26 © VictorRentea.ro
a training by
Simplify existing code
without changing its external behavior
Refactoring
DO NOT BREAK
PRODUCTION
27 © VictorRentea.ro
a training by
29 © VictorRentea.ro
a training by
I'm afraid to refactor
because we don't have tests
It's impossible to test a
200-lines method!
The Vicious Circle of Legacy Code
Pair Programming
(80% less bugs)
Coding Katas!
TDD Practice
30 © VictorRentea.ro
a training by
Safe Refactoring Tips
Next IDE Refactoring Fails Stress
Don't Break Compilation
(unless exploring)
Automated Refactoring
as much as you can
Decompose Large Changes
into small, safe moves
Use Quick-fix
to keep your focus on the design
(Alt-Enter / ⌥-Enter)
31 © VictorRentea.ro
a training by
Time
TIME FRAME
SPEED
32 © VictorRentea.ro
a training by
"I don't have time. I'm too busy"
Being busy is a form of laziness
- Tim Ferriss
Habits of Efficient Developers
by Daniel Lebrero
Stop! and Reflect.
Focus on what matters.
33 © VictorRentea.ro
a training by
Improve Your Focus
Turn off desktop/mobile notifications
Automate Stuff
Pomodoro 25/5
No morning inbox
Max 30 min meetings
 Digital Detox
Master your IDE ➔
Get your brain to focus
Chris Bailey
IntelliJ Productivity Tips
Victor Rentea
35 © VictorRentea.ro
a training by
Time
TIME FRAME
SPEED
36 © VictorRentea.ro
a training by
Estimates
37 © VictorRentea.ro
a training by
Emotionally Involved
38 © VictorRentea.ro
a training by
Ever-changing Requirements
40 © VictorRentea.ro
a training by
NO
41 © VictorRentea.ro
a training by
technical
functional (complex requirements)
iterations
(the point of Agile)
prototype/POC
Estimations Risks
42 © VictorRentea.ro
a training by
Time & Fear ☺
43 © VictorRentea.ro
a training by
The Best way to understand code is to Refactor it
44 © VictorRentea.ro
a training by
You lost it! You got carried away...
45 © VictorRentea.ro
a training by
3 hours later, you commit:
code improvements
refactoring
I gotta leave
Major changes
46 © VictorRentea.ro
a training by
47 © VictorRentea.ro
a training by
48 © VictorRentea.ro
a training by
Explore
49 © VictorRentea.ro
a training by
Exploratory Refactoring
Discover
Timeboxed: eg 15 min.
Revert.
Ctrl -
Missing from our Practice:
50 © VictorRentea.ro
a training by
refactoring idea
Long-lived Feature Branch
Source Control
51 © VictorRentea.ro
a training by
Merge Conflicts
Top annoying things in Dev's life:
➢ Interruptions
➢ Refactoring Tests
➢ Long meetings, and
52 © VictorRentea.ro
a training by
Trunk Based Development
(requires maturity & discipline)
Git Flow
(merge conflicts, redo-refactor)
Long Branches Inhibit Refactoring
if (easyBoxReturnFeature) {
// feature under develop
}
Feature Toggle
+ incremental DB migrations
Preliminary Refactoring
(separate Pull-Request)
53 © VictorRentea.ro
a training by
54 © VictorRentea.ro
a training by
Micro-commits
Break a large change set into:
Large + Safe Automated Refactoring
Manual Refactoring
Adding Behavior
+ Easier Code Review + Less Bugs
- Prior Exploration Needed
to identify the steps
A Commit Message Notation: https://github.com/RefactoringCombos/ArlosCommitNotation
Separate
Commits, or
Preparatory
refactoring PR
56 © VictorRentea.ro
a training by
What Stops Refactoring: Recap
Fear
➔ tests, pair programming
➔ practice
Time
➔ Proper estimates
➔ Improve Effectiveness
Rushing
even without time pressure
Lack of Consensus
➔ team design brainstorm
Huge PR - Rejected
➔ Trust
➔ Micro-Commits
Fear of Breaking some Eggs
to make the omelet
Merge Conflicts
➔ short-lived branches
➔ trunk-based
YOLO-driven developer
A. Make it fun, play together
B. Legacy Experience TM
Lack of Skills
extract a method ?!!
➔ Learn Code Smells
Unknown Code
Refactoring = Learning
VictorRentea.ro
57
Worse
Code
(hours-days)
Initial Chaos
Code
Quality
Time
You are here
The Deepest, most impactful refactoring starts with making a bigger mess
"You have to break some eggs
to make an omelet"
Wow!
I see a deep refactoring
eg. join two 100-lines method➔ one 200-lines method
VictorRentea.ro
58
Worse
Code
(hours-days)
Code
Quality
Time
You are here
The Strength to Revert
(despite emotional involvement)
Ctrl-
A day without no Ctrl-Z
is a day you didn't learned anything
... and the speed to get to some conclusions fast
You need
VictorRentea.ro
60
Code Smells
“If it stinks, change it.”
— Grandma Beck, discussing childrearing philosophy
VictorRentea.ro
61
Large Method
God Class
Too Many Parameters
Data Clumps
(String, String, Long) ➔ Address
> 20 lines
> 200 lines
> 4
All numbers are arbitrary. Find your own comfort zone
65 © VictorRentea.ro
a training by
Enrich your Domain Language
by Discovering Value Objects
Simplify your code
Constraints Methods Reuse in larger Entities
VictorRentea.ro
66
Speculative Generality
Middle Man
person.getAge()
int getAge() {
return bio.getAge();
}
person.getBio().getAge()
Data Classes
get/set mania ➔ OOP
Feature Envy
Function ❤️ the state of an object
Primitive Obsession
➔ PhoneNumber, OrderId, enum
➔ 💋 KISS Principle
VictorRentea.ro
67
Primitive Obsession
Map<Long, List<Long>> customerIdToOrderIds
redeemCoupon(Long, Long, String)
68 © VictorRentea.ro
a training by
Map<Long, List<Long>> customerIdToOrderIds
Map<CustomerId, List<OrderId>> orders
redeemCoupon(Long, Long, String)
redeemCoupon(CustomerId, CouponId, PhoneNumber)
Micro-Types
VictorRentea.ro
69
Primitive Obsession
Make concepts explicit
by introducing new small classes
Even if it's a single
String → PhoneNumber
Long → CustomerId → ID type:
@Value
class CustomerId {
Long id;
}
Escape the
70 © VictorRentea.ro
a training by
Map<Long, List<Long>> customerIdToOrderIds
If the only usage of a map is:
for (Long customerId : map.keySet()) {
List<Long> orderIds = map.get(customerId);
...
}
Code Smell: Iterating over Map Keys
List<CustomerOrderIds>
You might be missing an abstraction (class):
class CustomerOrderIds {
private Long customerId;
private List<Long> orderId;
...
}
(or entries)
VictorRentea.ro
71
VictorRentea.ro
72
Divergent Changes
Duplicated Code
Shotgun Surgery
m()
Is it a bug or a feature?
<>
DRY SRP
Is terrible when changes
VictorRentea.ro
73
switch
repeated switches loops
for (e : list) {
A();
B();
}
list.stream()...A..
list.stream()...B..
vs Polymorphism
vs "functional" switch in java17
vs enum with logic/Function refs
VictorRentea.ro
74
Long-Lived
Temporary Field
x.setX(1);
x.doStuff();
out = x.getY();
Temporal Coupling
out = x.doStuff(1);
Mutable Data
+ Multi-Threading =
reads from X field
and writes to Y field
VictorRentea.ro
75
Code Smells Sheet
Defeating the Evil starts with Naming It
76 © VictorRentea.ro
a training by
Code Smells Sheet
Defeating the Evil starts with Naming It
https://sourcemaking.com/refactoring/smells
Long Method
God Class
Data Clumps
Long Parameter List
Primitive Obsession
Data Class
Feature Envy
Middle Man
Duplicated Code
Shotgun Surgery
Divergent Code
Repeated Switches
Loops
Temporary Field
Long-Lived Mutable Data
Speculative Generality
Comments
Chapter 3
Many more + Solutions in
or: https://sourcemaking.com/refactoring/smells
VictorRentea.ro
blog, best talks, training offer
@VictorRentea
The End
victorrentea.ro/community
Join me:
Stay into
The Light
sourcemaking.com/refactoring
First Half + Ch. 17 Ch.3 Code Smells For rookies Coding Katas
kata-log.rocks/refactoring
cleancoders.com
refactoring.guru
Share your thoughts
The Beginning

Refactoring blockers and code smells @jNation 2021

  • 1.
    VictorRentea.ro 21 victor.rentea@gmail.com ♦ ♦@victorrentea ♦ VictorRentea.ro
  • 2.
    Victor Rentea VictorRentea.ro Recorded Talks,Blog, Video Courses, ... Independent Trainer Founder of Bucharest Software Craftsmanship Community Java Champion ❤️ Simple Design, Refactoring, Unit Testing ❤️
  • 3.
    Technical Training 500 days (200+online) 2000 devs 8 years 50+ companies Reach out to me: Hibernate Spring Func Prog Java Performance Reactive Prog Design Patterns Pragmatic DDD Clean Code Refactoring Unit Testing TDD any lang @victorrentea Intense More: VictorRentea.ro Workshops: victorrentea.teachable.com
  • 4.
  • 5.
    25 © VictorRentea.ro atraining by Refactoring What must we do every single day? What’s that?
  • 6.
    26 © VictorRentea.ro atraining by Simplify existing code without changing its external behavior Refactoring DO NOT BREAK PRODUCTION
  • 7.
  • 8.
    29 © VictorRentea.ro atraining by I'm afraid to refactor because we don't have tests It's impossible to test a 200-lines method! The Vicious Circle of Legacy Code Pair Programming (80% less bugs) Coding Katas! TDD Practice
  • 9.
    30 © VictorRentea.ro atraining by Safe Refactoring Tips Next IDE Refactoring Fails Stress Don't Break Compilation (unless exploring) Automated Refactoring as much as you can Decompose Large Changes into small, safe moves Use Quick-fix to keep your focus on the design (Alt-Enter / ⌥-Enter)
  • 10.
    31 © VictorRentea.ro atraining by Time TIME FRAME SPEED
  • 11.
    32 © VictorRentea.ro atraining by "I don't have time. I'm too busy" Being busy is a form of laziness - Tim Ferriss Habits of Efficient Developers by Daniel Lebrero Stop! and Reflect. Focus on what matters.
  • 12.
    33 © VictorRentea.ro atraining by Improve Your Focus Turn off desktop/mobile notifications Automate Stuff Pomodoro 25/5 No morning inbox Max 30 min meetings  Digital Detox Master your IDE ➔ Get your brain to focus Chris Bailey IntelliJ Productivity Tips Victor Rentea
  • 13.
    35 © VictorRentea.ro atraining by Time TIME FRAME SPEED
  • 14.
    36 © VictorRentea.ro atraining by Estimates
  • 15.
    37 © VictorRentea.ro atraining by Emotionally Involved
  • 16.
    38 © VictorRentea.ro atraining by Ever-changing Requirements
  • 17.
  • 18.
    41 © VictorRentea.ro atraining by technical functional (complex requirements) iterations (the point of Agile) prototype/POC Estimations Risks
  • 19.
    42 © VictorRentea.ro atraining by Time & Fear ☺
  • 20.
    43 © VictorRentea.ro atraining by The Best way to understand code is to Refactor it
  • 21.
    44 © VictorRentea.ro atraining by You lost it! You got carried away...
  • 22.
    45 © VictorRentea.ro atraining by 3 hours later, you commit: code improvements refactoring I gotta leave Major changes
  • 23.
  • 24.
  • 25.
    48 © VictorRentea.ro atraining by Explore
  • 26.
    49 © VictorRentea.ro atraining by Exploratory Refactoring Discover Timeboxed: eg 15 min. Revert. Ctrl - Missing from our Practice:
  • 27.
    50 © VictorRentea.ro atraining by refactoring idea Long-lived Feature Branch Source Control
  • 28.
    51 © VictorRentea.ro atraining by Merge Conflicts Top annoying things in Dev's life: ➢ Interruptions ➢ Refactoring Tests ➢ Long meetings, and
  • 29.
    52 © VictorRentea.ro atraining by Trunk Based Development (requires maturity & discipline) Git Flow (merge conflicts, redo-refactor) Long Branches Inhibit Refactoring if (easyBoxReturnFeature) { // feature under develop } Feature Toggle + incremental DB migrations Preliminary Refactoring (separate Pull-Request)
  • 30.
  • 31.
    54 © VictorRentea.ro atraining by Micro-commits Break a large change set into: Large + Safe Automated Refactoring Manual Refactoring Adding Behavior + Easier Code Review + Less Bugs - Prior Exploration Needed to identify the steps A Commit Message Notation: https://github.com/RefactoringCombos/ArlosCommitNotation Separate Commits, or Preparatory refactoring PR
  • 32.
    56 © VictorRentea.ro atraining by What Stops Refactoring: Recap Fear ➔ tests, pair programming ➔ practice Time ➔ Proper estimates ➔ Improve Effectiveness Rushing even without time pressure Lack of Consensus ➔ team design brainstorm Huge PR - Rejected ➔ Trust ➔ Micro-Commits Fear of Breaking some Eggs to make the omelet Merge Conflicts ➔ short-lived branches ➔ trunk-based YOLO-driven developer A. Make it fun, play together B. Legacy Experience TM Lack of Skills extract a method ?!! ➔ Learn Code Smells Unknown Code Refactoring = Learning
  • 33.
    VictorRentea.ro 57 Worse Code (hours-days) Initial Chaos Code Quality Time You arehere The Deepest, most impactful refactoring starts with making a bigger mess "You have to break some eggs to make an omelet" Wow! I see a deep refactoring eg. join two 100-lines method➔ one 200-lines method
  • 34.
    VictorRentea.ro 58 Worse Code (hours-days) Code Quality Time You are here TheStrength to Revert (despite emotional involvement) Ctrl- A day without no Ctrl-Z is a day you didn't learned anything ... and the speed to get to some conclusions fast You need
  • 35.
    VictorRentea.ro 60 Code Smells “If itstinks, change it.” — Grandma Beck, discussing childrearing philosophy
  • 36.
    VictorRentea.ro 61 Large Method God Class TooMany Parameters Data Clumps (String, String, Long) ➔ Address > 20 lines > 200 lines > 4 All numbers are arbitrary. Find your own comfort zone
  • 37.
    65 © VictorRentea.ro atraining by Enrich your Domain Language by Discovering Value Objects Simplify your code Constraints Methods Reuse in larger Entities
  • 38.
    VictorRentea.ro 66 Speculative Generality Middle Man person.getAge() intgetAge() { return bio.getAge(); } person.getBio().getAge() Data Classes get/set mania ➔ OOP Feature Envy Function ❤️ the state of an object Primitive Obsession ➔ PhoneNumber, OrderId, enum ➔ 💋 KISS Principle
  • 39.
    VictorRentea.ro 67 Primitive Obsession Map<Long, List<Long>>customerIdToOrderIds redeemCoupon(Long, Long, String)
  • 40.
    68 © VictorRentea.ro atraining by Map<Long, List<Long>> customerIdToOrderIds Map<CustomerId, List<OrderId>> orders redeemCoupon(Long, Long, String) redeemCoupon(CustomerId, CouponId, PhoneNumber) Micro-Types
  • 41.
    VictorRentea.ro 69 Primitive Obsession Make conceptsexplicit by introducing new small classes Even if it's a single String → PhoneNumber Long → CustomerId → ID type: @Value class CustomerId { Long id; } Escape the
  • 42.
    70 © VictorRentea.ro atraining by Map<Long, List<Long>> customerIdToOrderIds If the only usage of a map is: for (Long customerId : map.keySet()) { List<Long> orderIds = map.get(customerId); ... } Code Smell: Iterating over Map Keys List<CustomerOrderIds> You might be missing an abstraction (class): class CustomerOrderIds { private Long customerId; private List<Long> orderId; ... } (or entries)
  • 43.
  • 44.
    VictorRentea.ro 72 Divergent Changes Duplicated Code ShotgunSurgery m() Is it a bug or a feature? <> DRY SRP Is terrible when changes
  • 45.
    VictorRentea.ro 73 switch repeated switches loops for(e : list) { A(); B(); } list.stream()...A.. list.stream()...B.. vs Polymorphism vs "functional" switch in java17 vs enum with logic/Function refs
  • 46.
    VictorRentea.ro 74 Long-Lived Temporary Field x.setX(1); x.doStuff(); out =x.getY(); Temporal Coupling out = x.doStuff(1); Mutable Data + Multi-Threading = reads from X field and writes to Y field
  • 47.
    VictorRentea.ro 75 Code Smells Sheet Defeatingthe Evil starts with Naming It
  • 48.
    76 © VictorRentea.ro atraining by Code Smells Sheet Defeating the Evil starts with Naming It https://sourcemaking.com/refactoring/smells Long Method God Class Data Clumps Long Parameter List Primitive Obsession Data Class Feature Envy Middle Man Duplicated Code Shotgun Surgery Divergent Code Repeated Switches Loops Temporary Field Long-Lived Mutable Data Speculative Generality Comments Chapter 3 Many more + Solutions in or: https://sourcemaking.com/refactoring/smells
  • 49.
    VictorRentea.ro blog, best talks,training offer @VictorRentea The End victorrentea.ro/community Join me: Stay into The Light sourcemaking.com/refactoring First Half + Ch. 17 Ch.3 Code Smells For rookies Coding Katas kata-log.rocks/refactoring cleancoders.com refactoring.guru Share your thoughts The Beginning