More East11 Jun 2011
Recently I was a special guest on ADDcasts back in episode 4:.
After the episode aired I received some questions about East. What follows is part of my response which I am posting to continue the discussion on East in the hope that more people try the technique.
I’m interested in learning new ways to write software and make what I am writing more readable to others, so I’m ok with people disagreeing. I learn more if they do. I think I led with a poor example and reasoning as I have limited time to think on weekends as I look after my twin boys who are 2.5
Lets forget the accessor and mutator side of things and just focus on the implications of asking an object for information and working on it, rather than asking that object with the information to do the work. This is the key principle - Tell Don’t Ask
When we allow callers to ask for data and we want to know what they do with that data we have to find all callers and look in detail at what they do with the data. Usually what they do with it will be spread over multiple statements, even if those statements just a ‘get’ of multiple attributes. When they can ask for each ‘field’ this task becomes larger and possibly harder. Why did they ‘get’ just 2 attributes here but in other code they ‘get’ 6?
In addition, when we allow callers to ask for the data I usually see multiple callers doing the same processing on the returned data. This might be as subtle as a conversion to uppercase, but I have seen much more repetition creep in. How often have you seen this in the caller:
This repetitive processing should be in one place - and highlites a missing concept/abstraction. For example, Why does the caller iterate over the returned_collection?
When you face the calls East and ask the object with the information to do the work then the use cases become more evident. For example, ‘customer.printOn envelope’ provides more meaning than looking at multiple call sites. Note I’m not discussing the implementation of Envelope here - personally I’d be using an object over a lambda, even if in Ruby/Smalltalk.
When the use cases are encapsulated in an object like Envelope then the commonality of multiple ‘functional object’ objects can be refactored and kept DRY.
Testing in the case where you can ask an object for attributes requires a lot of setup like ‘when I call this accessor, then return that value’. In contrast when faced East the testing changes. Usually there is a simpler expectation like ‘when I call this method, that object receives these calls.’
What I would like to see happen is for people to try this approach and see how it effects their design and their process of getting from A to B. Personally I have found the process to be more effective in time and the ability to understand the resulting code, which I also find there is less of.