5. My goals for the talk
• Show how what I have learned at coderetreats
have been taken into production use
• GOAL 1: Encourage us to practice the craft
• Show what I’ve done – Test Driving my design
• Show steps rather than finished ‘product’
• GOAL 2: initiate discussions on what I’ve done
• Learn
• GOAL 3: reflect on my work and decisions and how
they actually seem now.
6. Tips for listeners
• There’s going to be a lot of code
• Rather than reading the code, try to smell it.
• How clean the code seems to be?
7. What I’ve done – what I believe in
• Is not either good or bad.
• It has bugs (I’ve seen those)
• It provides value to the customer every day
8. What is valuable (for someone)
• Client
• clients of the Client
• Myself & fellow ambientians
• How likely this code is going to change?
• How likely the change I make is going to introduce
bugs in future additions to this feature
9. Key process decisions
• TDD as design tool.
• Unit tests for changes
• Practice TDD in real environment. Try to get feedback
• Refactor often
• Keep tests clean
• ”if it is not important for the test, it is important not to
be in the test!”
• Note: Builder pattern
10. Key process decisions
• Use proper tools
• GIT, IntelliJ IDEA, VIM
• Hamcrest, mockito, various other open-source
components
11. 4 elements of simple design
1. Passes its tests
2. Minimizes duplication
3. Maximizes clarity
4. Has fewer elements
12. Coderetreat
• 1 day of coding
• Pair programming, 6 different pairing partner
• Learn through pairing
• Deliberate practice
• experiment
13. Key takeaways from coderetreats
• Baby steps – commit to git often. Rebase to
keep git log clean
• TDD-as-if-you-meant-it
• Avoid conditionals, switches, try/catch
• Only 4 lines per method
• Avoid naked primitives
• Only one assert/behavior per test
• Sapir-Whorf hypothesis
• Tell – Don’t ask: no getters/setters for objects
14. Object calisthenics
1. One level of indentation per method
2. Don’t use the ELSE keyword
3. Wrap all primitives and Strings
4. First class collections
5. One dot per line
6. Don’t abbreviate
7. Keep all entities small
8. No classes with more than two instance
variables
9. No getters / setters / properties
23. What I did was a brief study
• How the methods are used in the service?
• Grails-based service (200LOC) uses it
• Determine the current responsibilities
• Service builds valid parameters, DAO consumes it.
• Where the changes could be made?
• Both the service & DAO
• Is the method likely to change later?
• YES
29. Key decisions
• Factory to hide implementation details
• Sometimes Criteria handled Date, sometimes
Calendar
• Make it first to work, refactor then.
• Create a ProductSearchCriteria per type –
think about the name of the object
• There were no tests before – try to make
minimal impact on code.
30. Test on localhost.
• The context is a bit more complex than I
originally thought:
• In one case, it was not enough to limit on
Date/Calendar
• Thus, the original factory-idea would turn into a
bit more complicated problem
32. Firstly: factory into builder
• Build what you need – add items to
CompositeSearchCriteria as need arises
• Again – do the minimal changes to the grails-
service in order to minimize errors
46. Learnings
• Fast to refactor
• Next time: start from integration test
• But one cannot integration test the whole – too many
parameters
• Minor changes somewhere in the controller code
caused it to fail on other places.
• Later, a colleague joined me. His first task was
to add a new concept to domain.
• Also for search
48. Targets
• System used to have ~ 20 different attachment
types.
• Only 5 were needed.
• Earlier supported only 1 attachment / type /
product. Now should support more.
50. Decision to be made
• Where to start?
• The only (business) knowledge came from the
previous changes
• I decided to tackle the switch-case structure
• It was spread 4 times throughout the code
• To ease the change from 20 to 5
66. Things not to do
• Have a constructor to throw an Exception.
• How would I change this now:
• Factory to create the directory
• Create AttachmentDirectory only if dir exists
• ready?
70. AttachmentFile(Factory)
• Similar concept with AttachmentFile and
AttachmentFileFactory
• With one difference
• AttachmentFile is interface and has two concrete
classes PlainAttachmentFile and
WebImageAttachmentFile
• Use of Template-pattern (which changed a lot
later)
76. AttachmentFile
• Too many responsibilities.
• Would turn up with lot of methods. I needed to
do something.
• Did try to not to repeat myself (not shown – ask
for more info later)
82. Steps
• Factory to create an AttachmentFile
• Factory creates a AttachmentFileProcess –
process to move/copy/clone/delete the
AttachmentFile
• For specific AttachmentFileType, it does
different things
• The execute method takes one argument,
AttachmentFileAction, which either is
move/copy/clone/delete/rename
94. And that led to
• New class: AttachmentFileName
• A domain logic for handling name of the Attachment
• I’m working with this. Now.
95. Learnings
• Slow to refactor
• Test-Driven design can work even in brown-field
projects
• Integration to old system required integration tests
• How valuable the changes were to the customer
• With my current understanding:
• Split the changes to two – deploy both separately.