After an afternoon at Redis and having done the same with MongoDb I’m siding with redis and I suspect it is the sets feel and separating out data from indexing.
Review: Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pyrce (2010)
We write code that is easy to maintain over code that is easy to write.
Maintainability is the mantra of the TDDist and I think that this book credibly demonstrates – to the new and experienced – what this looks like in practice. The book is focussed on unit testing in which they make a nice distinction from acceptance and integration testing (p.9). Importantly, unit testing should also be performed within the context of the whole through a test tracer (end-to-end test rig) called a walking skeleton (ch 10). Working between the whole (system) and the specific parts is something that is easy to forget to do and is done at your own peril. By setting up the test harness framework as a walking skeleton and then going into the specifics using mocking strategies I think is an important reminder that interaction testing can be maintainable. Their use of jMock’s allowances vs expectations is an important reminder that we need to use DSLs not only in our domain objects but also in our tests. By doing so, our tests become expressive through a declarative style rather than a procedural one which allows us to understand the intentions of the code and listen to what our tests have to say about our design (p.262-4). I took these reminders back to an old code base and started listening to the tests – I was surprised how I could hear criticisms from non-TDDers about the intrusion of the tests in ways that made think about improvements and yet still remain resolved that test-first makes my code maintainable but not always easy and that I need to make it more expressive and simpler yet.
There is a good introductory fifth of the book dedicated to the fundamentals of why this is important for growing object-oriented software. I particularly liked that they stayed with the Evans’ distinction between objects and values: objects have identity and relationships with each other, whereas values have no identity should be immutable quantities/measurements. The basis though for their later sections are the practical implications of what you can do with objects and values. Different strategies can be used with objects depending on object peer stereotypes: dependencies, notifications and adjustments (p.52). These are the different types of relationships that objects have with each other which help us think through the types of designs we want. Alternatively, values can be refactored via three basic techniques: breaking out, budding off and bundling up (p.59) – basically, ways of reducing complexity through splitting out differences, marking new concepts but deferring nomenclature and grouping similarities. Growing object-oriented software uses examples in Java and more specifically a mocking framework that is not available in C# (or Ruby) where I do most of my work. Yet, I found this perhaps better than if I had examples in my familiar idiom – I will now look at Moq and MSpec to see how I might use jMock’s declarative nomenclature to simplify and make more expressive my tests.
pass behaviours rather than data
This is what I know my tests would tell me if I was listening to them – I know that my style has been pass values around the stack (data style). Instead, I need to pass around more behaviour in the form of callbacks. These are going to give to me precise interfaces with better information hiding (separation of concerns) and clearer abstractions. I am going to go back to my code base and probably get rid of some of the Microsoftisms – interfaces with an “I” prefix and really start to think what is its role and related classes. I’m going to look at constructors to explore how objects communicate with each other and the relationships are between them. In short, the book really reminds me that naming is hard but tests help you get clearer and that that is time well spent to grow you software.
There are only two hard problems in Computer Science: cache invalidation and naming things – Phil Karton