I’ve always been a strong believer in the benefits of reading others’ code. This belief has been recently reinforced during a discussion with Alexis. The argument is that there’s no better way to learn new idioms, programming patterns (in the generic sense, not the GoF sense) and applied algorithms than when reading code. And that’s one more benefit of open source. By having so much code out there you can read, there’s far more opportunity to learn than, say, 10 years ago. I’d even go as far as saying that the open source movement is making us all, developers, better, by giving us very valuable sources of knowledge. Don’t get me wrong, there’s always been some opportunity to learn before from others’, like the code of your team’s guru, but we now have far more choices and also much better quality code to choose from. And probably also much worse but you can learn from that too and before you’re good enough to learn from bad code, you’ll have to make good choices.
I’ve learned Javascript a lot by reading Prototype. Same thing for Ruby, starting from Rake with its nicely structured code and more recently
with RSpec, which is full of clever meta-programming techniques. Java is a bit different, when I started the net was less ubiquitous, there was less good quality open source libraries available. But the API sources were distributed with the JDK and there was quite a bit to see in there too (both good and bad). The Oswego Concurrent library, now part of the JDK, is also a priceless mine of best practices when you need to write thread-safe code.
More generally, the same thing can be achieved at the design and the architectural level. Just check how things work and what the implications are. For example, from using and checking the guts of different big Java persistence frameworks, I can tell you there are basically 3 ways to make some class persistent in Java, which requires knowing when an object attribute value has changed: code generation (either compile time or runtime), byte-code enhancement or reflection. Each approach has its strengths and shortcomings. Hibernate uses the first technique by generating classes at runtime that subclass your persistent classes. It’s almost completely transparent until you start caring about class identity: the classes you’re dealing with have changed. Which can lead to some nasty bugs with inheritance trees and the usage of instanceof. Which doesn’t mean Hibernate is a bad tool, others also have the problems that can come with their respective design decisions. It’s just good to know them, to know why they exist and see if some similar designs you’re working on could be facing the same tradeoffs.
As for architectures, there’s also a lot to learn from past failures, the disillusions and the incremental improvements over the years. J2EE, SOAP-based Web Services, RESTful Web Services, JBI, SCA, what do they all offer? Which benefits? Which compromises? But when you go from code to design to architectures, the number of details to grasp grows significantly, making objective judgment also significantly harder.
Reading the code of interesting libraries and checking how some pieces of software work is a way to reach our collective knowledge, as developers. All this code out there is both our toolbox and our Wikipedia. So read more. And also, don’t forget to write and offer your best looking code, it’s as good a way to teach as any.
Matthieu Riou on December 3rd 2007 in Uncategorized