The best practices? Why would you need that?
Added: August 10, 2010
It has been already some time since I started to oppose to idea of the Best Practice. Somehow it felt like an excuse to avoid thinking and using out-of-box solution. But I could not express my concerns well enough for the Best Practice Seekers and Followers to even start doubting it.
Now, I can use very good article Death to Best Practices written by Ted Neward. I encourage everybody to read it as well as an article linked there, but I offer my favourite part:The point is, best practices just don’t exist. They are an attempt to take a solution to a problem out of the context and apply them across the entire spectrum, and that essentially invalidates the entire thing. A solution is only useful when considered in context.I am looking forward for comments saying you actually can breathe under water, you just need to... But that would be only cognitive dissonance at work. There is a value in the best practices, I have never doubted it, but I always suggested to use name good practices to show they are not universal truth. IMHO their value is in learning how experts solve particular problem in particular context, allowing to think whether it is a good match in our context, discussing differences in contexts and to think whether we could change our assumptions about problem we are trying to solve. I have touched this topic before in Giving gifts versus conceiving rules and also in Is Javadoc useful?
Don’t believe me? Consider this challenge: when is it not a best practice to breathe? When you’re under water, of course.
(Unless you’re a fish. Or a frog. Or maybe a prince turned into a frog.)
Point is… context matters, folks.
I've just found interesting post Test Driven Code Review. Its title and the 2nd sentence caught my attention:
When reviewing or just reading such code, it's often best to first read the tests.That is something I started to use some time ago and I had very good experience with it many times. But not always. As Philip Zembrod writes further he had similar experience and coined terms well-specifying tests and poorly-specifying tests. I like them. What could be the better place to understand code you've just got to review without deep understanding of requirements and domain it touches? Well, I agree with the author it should be tests. But they have to be clean, easy to read and simple. After being guilty myself in writing obscure tests in the past, I try to make them as easy and concise as possible for last couple of years. I think my turning point was when I (gradually with time) created a unit test using 13 mocks. Every time some of test (usually more at once) failed I had to go to deep analysis whether I really introduced bug or I just need to tweak one of those inconvenient mocks, because requirements changed.
I have learned a lot from that experience
- Limited responsibility of class will ask for less mocks. It is always possible to rearrange responsibilities in some way to allow simpler testing (and understanding both production and test code).
- Test should explain main points, hiding irrelevant details (like creation of data it needs, but they are not the reason for existence of this test; hiding details of how mocking library works while saying what you want to achieve).
- Test should be concise, only couple of lines all focused to tell you a story. What environment you have, what you do with tested class and what effects you should see as the result.
But not everybody does
Sad part is I always find hard to read tests that are completely obscuring the main point. Apart from plenty of "easy" to fix tests I have seen also couple of ugly ones. The worst was 3500 lines long test with 32 mocks! It was worse than really thick book with unappealing name. I've never bothered to look at production code. (Fortunately I did not need to). OK, there is even sadder part: I am afraid the author(s) will never learn anything from this test experience. Maybe only one incorrect thing - unit testing is meant to be hard :-)Back to reviews
I usually try to spread good ideas and I've found the code reviews are pretty good medium for suggesting simple improvements in tests without being caught as mentoring. Many times I found developers are too proud to accept explicit help, which is pity in my opinion. Disadvantage of this approach is high probability helped person will miss the bigger picture. But that might come later.A few people asked me when I am going to publish more posts here.
Eventually I will, but my urge to explain things and express my opinions is currently satisfied with my voluntary actions in my work. I had to write several articles where I try my best to express myself to sell my ideas so there is not much left to say at this blog. And it looks like it will be same for some time. It also fulfills my resolution to get better in writing (one reason I started this blog). The only disadvantage of my current way is that I have lost about 1 hour of writing yesterday as I used Back button in browser and our wiki did not help me to locate overwritten stuff. That would not happen on my blog as I could take lost text from log. But it helped me to make it better today :-) On the other hand, I have real feedback there and it is good feeling to see people accepting my ideas and acknowledge my effort. BTW, my writing efforts at work are about unit testing, but I cannot publish any part here due to ownership of stuff produced by me at work...Today I have done the first session How to make unit testing better with my colleagues. I am satisfied with my performance, as it was the biggest audience I have ever had. It took me long time till I got enough courage to start - I was thinking about introducing "my tricks" to wider audience of my colleagues since May... (but I've done something in my team sooner).
I was not sure how it will be accepted. Now I know my fears were unfounded. Colleagues appreciated my effort and are happy to continue, they suggested mailing list and wiki to track discussed points. But they might not be aware of fact that they will not be only passive listeners next time :-D If everything goes well, I can imagine that we will get to general topics like design, design principles, clean code and anything else that developers should want to discuss soon. I plan to show TDD soon. I am looking forward to that, but again I am bit afraid that will end up with "20 bored spell checkers". I need to do that interactive as much as possible.Uncle Bob talks about ethics of software professional, quality, readable code, reviews, code analysis and all other important things. I can only recommend to listen it to everybody. It contains serious stuff intermingled with jokes and I have enjoyed it a lot. http://elegantcode.com/2008/09/30/cast-cast-15-uncle-bob-martin/
Last entry inspired me to think about books I really liked, they taught me a lot and I wish everybody around me have read too :-) Here it is, it is not complete and their order is not meant as ranking.
- Martin Fowler: Refactoring Improving the Design of Existing Code
- Michael Feathers: Working Effectively with Legacy Code
- Kent Beck: Test Driven Development: By Example
- Dave Astels: Test-Driven Development: A Practical Guide
- Eric Evans: Domain-Driven Design
- Martin Fowler: Patterns of Enterprise Application Architecture
- Gerard Meszaros: xUnit Test Patterns: Refactoring Test Code
- Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides: Design Patterns: Elements of Reusable Object-Oriented Software
- Alan Shalloway: Design Patterns Explained: A New Perspective on Object-Oriented Design
- Andrew Hunt, David Thomas: The Pragmatic Programmer: From Journeyman to Master
- Tom DeMarco, Timothy Lister Peopleware: Productive Projects and Teams
- Johanna Rothman, Esther Derby: Behind Closed Doors: Secrets of Great Management
- James Shore, Shane Warden: The Art of Agile Developement
- Robert C. Martin: Clean Code: A Handbook of Agile Software Craftsmanship
- (many): The ThoughtWorks Anthology
About 2 years ago I was handing my project over to my successor. He was younger, less experienced so apart of showing him details of project I was also giving him good advice.
I was talking about unit testing, TDD, something about design and that led me to refactoring. At the end of the session I gave him Refactoring book thinking how much I helped him. To my big surprise he came to me next day handing book back with words "I can click in Eclipse". I was shocked, not able to react. My first thought was probably something that I misjudged him. I realized whole point only later, but then I felt it is too late to return to that for him already closed matter. The real meaning of those words was "I don't know and I don't know I don't know.". Really - he thought that book talks only about things Eclipse can do easily. But that was huge mistake - it talks about more important things like what are code smells, how to detect them, how to achieve better design with small steps, what to do if simple refactorings fail or they don't lead to nicer result and so on. I believe this book taught me how to work a bit differently - be less concerned about immediate appeal of code I am currently writing, because I can change it easily when bigger picture is available. That I can Extract Method later when I know what it does and how to name it correctly. I do not worry about every aspect, because I know I can change it easily. And I know what my possibilities are, so I am able to spot opportunity when it occurs. I would say that spotting opportunity when it occurs is the most important part. If all code looks satisfying/passable to me, there is no possibility for improvement. I believe it was the first book that taught me something about aesthetics in code. Looking back to this "incident" I think I missed good opportunity to help him, but it is quite possible his ego did not allowed me to, so maybe my reaction was OK. Since then I try to be more persuative in similar situations. So if you stumble on me, trying to help you, be tolerant and patient, please :-)Recently I was trying to help my younger colleague with preparation of list of topics what he should learn. Well, it was my idea to provide such a list to him, I am not really sure if he was really interested in short term as his highest priority now is Java certification. My list included following:
- OOP
- design (principles)
- design patterns
- TDD
- refactoring and how to identify code smells
- writing expressive code
Then I've realized it is huge task list as none of those topics can be learned in "a week". Even worse, I am not able to prioritize them to help tackle this daunting task. My best offer is along the lines "learn everything at the same time".
I have to say I am really glad not being in the same position, that I need to learn everything again. It hurts just to imagine what I would need to learn. Of course, I still need to grow in all areas (as most of us), but it is easier to select some topics that interest me more just now and go through them without a rush. Or to jump from one topic to another.