retro for Practice: Object Calisthenics + TDD + Advent of Code
Small retro (end of part 1) How did it feel?
- at first, slow with having to check the rules
- at first, irritating because the constraints chafing me
- soon, surprisingly good: I could feel the constraints pushing me towards better design
What went well & should do more of?
- ‘remove duplication’ to draw out functionality without having to triangulate, feels so good! It has this smoothness to it. And it’s somewhere in between ’triangulate’ and ‘obvious implementation’
- triangulate to draw out separate parts of functionality
- first triangulate to draw out ‘multiplication’
- then triangulate to draw out ‘find 2 where sum==2020’
- in refactor: go over all rules, and over all code to see if anything breaks the rules
- I’m learning to spot the rule-breakers faster and faster
Big retro (end of part 2) Were my expectations correct?
1) Object Calisthenics is sufficient for TDD's Refactor step. No other refactors are needed.
I did some other refactors:
- rename class / method / variable
- extract method
- Keep All Entities Small (5 lines/method)
- clarity aka ’expresses intent’
- remove duplication
- maybe there should be a ‘x chars/line’ rule? It would have forced all of these
- inline variable / method
- formatting / removing unused things
- remove duplication to drive towards the right solution (avoiding triangulation)
- trigger: string literal / magic number
- too specific if statements (cf TPP?)
- tests clearly express required functionality
- cheating, not having to write a test ; reverted it ; wrote a test to force me to end up more in that direction ; and I ended needing it to make my test green!
- actual why: align with pattern in existing code
So there is some impulse for other refactors. But the bulk of them (41/55), were the ones from Object Calisthenics. Maybe in another round, I can try to see what happens if I ONLY do Object Calisthenics refactors…
2) The change-over from part 1 to part 2 will be seamless, not breaking the flow of coding.
Well, I stopped coding after part 1 was done. So in a way it broke the flow of coding. But let’s ignore that ;-)
I learned new things from the second part. I wanted to rename all the things from the first part to indicate that new learning
expenseReportFixer.findAnswer() -> expenseReportFixer.findAnswerFor2()
so I could add
expenseReportFixer.findAnswerFor3()
I forced myself to write a failing test first, and only do those changes in a refactor step. It felt really superfluous to wait with a refactor, until after the red&green steps. Because the refactor would have been unrelated to the test case. In the end I ended up forgetting to rename it. Maybe that’s related to me designing the entry-point of the code in the ‘acceptance test’. (which I added when I started with part 1 and when I started with part 2)
On the TDD flow, it didn’t have any impact. I could add a failing test and continue. A bit too easy, because I forgot the rename I intended to postpone until after an arbitrary red/green cycle.
It was not needed to do a big refactor before I could reuse existing part. In the TDD flow, after green, forced by Object Calisthenics, I could easily reuse parts.
How did it feel?
- smooth
- some concern about taking bigger steps (compared to the usual baby steps)
What went well & should do more of?
- tests clearly express required functionality ; it’s so much clearer
- JUnit 5 nested tests
- in refactor: go over all rules, and over all code to see if anything breaks the rules
- add a test to drive functionality ; vs ; ‘remove duplication’ as hidden functionality
- have getters everywhere, so green is easy, but refactor so I don’t use them