BECOME A BETTER DEVELOPER BY READING SOURCE CODE
By Steve Gordon
Hey friends! In this post, I’ll share some thoughts I have
concerning the conscious reading and study of source code. In my opinion,
reading code is a process which can help you become a more proficient software
developer. It has undoubtedly improved and influenced my software development
skills.
SHOULD I READ SOURCE CODE?
Yes, you should! The good news is, you’re already doing
this, day in day out when developing software. I’ve seen various statistics
over the years showing that a high percentage of our time as developers is
spent reading code, rather than writing it.
When you start on a new feature or on a bug fix, you have to
begin by understanding how existing code works. You may tackle this from the
unit tests which should clearly describe the desired behavior of existing code,
but often you will end up delving into the implementation code as well.
For this post, I consider this form of reading a given. What
I’m recommending here is that you make reading code a more conscious process
and most importantly read code that you have never seen before. Reading code
that you originally wrote or that you have worked on in the past is less likely
to impact and inform your future coding skills than exposing yourself to
previously unseen code.
Becoming better at reading and interpreting code will help
you when you tackle new features or bugs. You will be able to scan relevant
code for the information you need to begin work more quickly. Much as we can
train ourselves to read books more quickly, we can get quicker at reading and
comprehending software code.
WHY SPEND TIME READING SOURCE CODE?
Let’s think for a moment about how young children learn to
read and write. In the book, “Young Learners” by Caroline Linse, she states
that you need to read a word before you can write it. This sounds pretty
logical to me. By first reading words in context, you begin to understand their
meaning and appropriate use.
By reading books, you extend your vocabulary and pick up
techniques which you can later apply to your writing. This is just one reason
we study literature, through our formative years in school. Ultimately, as we
read more, we learn what works and what doesn’t.
The same then must surely be true for software code. I’m a
C# developer, but whatever your programming language of choice, there are many
rules to the syntax and keywords that you can use. A few simple keywords and
concepts can be combined into infinite possibilities for the code you produce.
There are many ways to achieve the same outcome, just as there are many ways of
saying or writing the same thing. While all may technically accomplish the same
goal, some tend to be more appropriate and easier to comprehend than others. In
code, some techniques may be more efficient than others too.
Have you even come across code written by a co-worker, or
even yourself, which is hard to read? I know I have! Hard to read code is hard
to maintain and can impede the development process. Just as in language, where
a poorly constructed paragraph can be confusing and difficult to absorb, code
can suffer the same fate. Those tricky paragraphs or blocks of code require
multiple read-throughs to parse the meaning and intent. By learning to read
more code we can also improve our writing skills to avoid producing
unintelligible code.
Improving one’s skills requires some deliberate effort.
Studying the work of those who are more experienced than yourself will
influence your own code in the future. Doctors, as just one example, go through
years of training even once qualified to practice medicine. They work alongside
more experienced doctors, watching at first, before attempting procedures
themselves. Great doctors will also study papers from those in their profession
to learn about new techniques and approaches.
This is something I feel we do less consistently in software
development. Some teams may manage this better than others. Pair or mob
programming is just one way to share skills between developers. My theory here
is that another vital technique for improving your own skills is to regularly
expose yourself to new code as part of a healthy continuous learning cycle.
A particularly relevant quote which summarises what I’m
trying to say in this section is from the great author, Stephen King.
“Can
I be blunt on this subject? If you don’t have time to read, you don’t have the
time (or the tools) to write. Simple as that.”
― Stephen King, On Writing: A Memoir of the Craft
WHAT SOURCE CODE SHOULD I READ?
If you’re still with me, I hope you’re sold on the concept
of reading code as part of your routine to help you continually improve as a
software developer. The next logical question then is what code should you be
reading?
At a broad level, I don’t think it matters. The sheer fact
that you are reading code is the important thing. Remember, though that all
software code is not created equal. Some of the source code that you read will
be markedly better written than other code. That’s perfectly fine. Both good
and bad code can help you refine your own approaches.
You don’t have to agree with the code for the reading of it
to be beneficial. Reading “bad” code can be hugely influential and informative.
If you read some code and dislike the style or you spot a functional flaw,
that’s fine. In doing so, you have identified a pattern or approach you don’t
like, or that doesn’t work. This can save you time when writing your own code
as you’ll hopefully avoid repeating the same mistake.
That said, you also want to be reading code which adds new
and more solid techniques or approaches to your coding vocabulary. I’ll discuss
some sources of code in the next section.
Reading code from multiple sources is crucial as you’ll
consciously (and subconsciously) learn patterns which repeat across the various
sources. When you see the same techniques, patterns and code trends used in
many places, it’s more likely a well-proven approach.
I focus my time on studying the internals of some of the C#
libraries which I use most often. Not only does this mean I improve my skills
by reading code in general, but also I learn about the inner workings of those
libraries which can further inform my use of them. It’s a double win.
Something I don’t do frequently enough, but I intend to
attempt, is to read code written in languages that I rarely or never use
day-to-day. Becoming extremely familiar with one software language is
undoubtedly useful, but extending your range of languages will also have
benefits. If you think about it, many of us see the benefit of learning a
second, and perhaps even third, spoken language. This makes communication with
people from other countries easier and will often further add to our knowledge
and use of our own native language.
Not only will second programming languages extend your
career options, but they will also make you appreciate the similarities and
differences from your primary language. We often see features in one language,
influence another. C#, for example, has more and more functional syntax evolved
first in F# appearing in each release. Some .NET features, such as Channels
were influenced by Go. We can prepare ourselves for these features by having
one eye on that second language.
WHERE CAN I FIND GOOD SOURCE CODE?
There are many potential sources for code. To name a few…
GITHUB
This is a vast resource of code written in practically every
language. Where better place to start? My personal favorites which have
influenced my C# code, are the ASP.NET Core and CoreFx libraries from Microsoft. I
find diving into the high-quality and considered code from the framework teams
to be a great way to learn.
Frameworks like these are excellent sources to review since
the code has high standards and is itself informed by the coding patterns used
at Microsoft. I have personally learned enormously from reading and learning
how the team structure extensible framework code. Just recently, I spent some
time thinking about the Task Parallel Library and discovering more about the
use of CancellationTokenSource in some code I was writing. By studying places
where Microsoft use this type, I was able to appreciate conventional approaches
which they use in their code.
GitHub has reasonable search functionality, so without even
downloading the code, you can navigate through a repository and learn directly
in the browser. For deeper dives, I prefer to clone the repository so that I
can navigate the code in more detail.
I also like to widen my coding vocabulary by looking into
the source of libraries I use, such as Polly and MediatR. This exposes me to other coding
styles that further broaden my appreciation of how code can be written. I don’t
necessarily like or agree with the structure of all code I read, but even then
I am more consciously recognizing what my own code preferences are. When
writing code, I am more deliberately able to dodge potential traps and poor
design decisions.
BLOG POSTS
The internet is stock full of excellent blog posts on
software development. You are sure to find many useful technical blogs which
include sample code snippets. These are excellent as they are often small
chunks of code which may be easier to digest in a brief sitting. Usually, the
code is annotated or explained in the blog post so you can verify your analysis
of the code against the author’s intent.
BOOKS
There are many great technical books available in both e-book and physical print formats. These two will contain code and clear explanations of how/why it works. In the last year, I learned a great deal about writing high-performance code by reading “Pro .NET Memory Management” by Konrad Kokosa.STACKOVERFLOW
You’re sure to find some great and some not so great code
examples on StackOverflow. Here the question and answer
format can be handy as you get to observe multiple opinions of different coding
styles. To focus on code more specifically, check out the Code Review area on StackExchange too.
INTERNAL SOURCE CONTROL
Earlier, I said an essential part of deliberate learning
through reading code was exposing yourself to code that you have never seen
previously. I think that is extremely important, but I do want to add that you
can learn a lot about work codebases too. There are sure to be projects and
repositories you’ve seldom worked with. By taking a little time to understand
them, you can get a feel for how those work. Should you ever end up supporting
them, you’ll have a real head start and be more familiar with code than perhaps
even the original authors.
As a new member on a team or when joining a new
organisation, you can swiftly get up to speed on the internal coding standards
and common patterns by studying the existing code. This will expedite your
onboarding and guide your personal development.
This is by no means an exhaustive list. Wherever you find
code, take a little time to read and appreciate it at a deeper level than you
usually would. You won’t regret investing the time to improve your software
development skills in this way.
HOW SHOULD I READ SOURCE CODE?
I’m sure everyone will have their own preferences within
this section. Ultimately do what feels right for you! I’ll share some of my own
approaches here which you may apply to kick-start your code reading adventures.
I typically like to focus on code which either does
something that I want to replicate the style of in the future, or which deepens
my knowledge of code I use daily. As I said earlier, this adds double the
return for the time I invest.
I tend to start work in GitHub. This strips me of my usual
tools and centres my attention on truly understanding what is happening in the
code. I try to find a high-level abstraction as a starting point and then
gradually dig deeper into the internals. I like to make notes in OneNote as I
study the code, describing the flow and how the code works. These are
short-form notes. This process is less about having a reference, although that
can be useful, than it is about embedding the knowledge into my memory. By
describing it in writing, I find that it sticks with me much longer.
Navigating code and forming a mental picture of the logical
flow is a handy skill. If you can learn this through reading code, it’ll pay
dividends when you’re next trying to fix a critical bug under pressure.
Once I have an overview formed the next step is to go
deeper. For this, I tend to clone the repository so that I can bring it into an
IDE or VS Code. There I can use the code navigation features to move around
more swiftly and really delve into the behaviour of the code. At this point,
I’m trying to understand why code has been written as it is. I like to think
about how I’d have chosen to approach a problem and contrast it with the actual
implementation. Is the author’s approach better or more efficient? Should I
file it away for when I next face a similar requirement?
Often the code may use APIs that I’ve never discovered when
writing code. I find that when I’m coding I will tend to use those APIs which
I’m more familiar with. These may not be the best methods to call or classes to
rely upon, but as I know no alternative, I keep using them. After reading some
code, if there are APIs I haven’t used before, I study the description and
method signature(s) to understand their designed use. This extends my code
vocabulary.
This second stage also improves my skills of working with
tools such as my IDE. I find tricks and shortcuts to save time when navigating
the code. Something I do often is to pull out a class into a window on my
second monitor so I can follow code flows more quickly. This is something I now
do often when I’m writing code as well.
I’m also on the lookout for language features or patterns I
don’t recognize. I quickly learn about the features of the latest version of C#
by seeing them used in the wild, so to speak.
WHAT IF I DON’T UNDERSTAND THE CODE?
That’s absolutely fine! At first, you won’t understand
everything you read, and that is, in fact, our goal here. You want to expose
yourself to new APIs or new syntax in the code which you read so that you
further your own code vocabulary. Reading code you understand easily, much like
reading a simple book, is not going to expand your writing skills.
Try to break things down into smaller chunks to work through
in your head. What is the code doing and also why has it been written that way?
Has the author used an approach to solving something you had not previously
considered? As you come up against language syntax or keywords you don’t
understand, stop and search for the documentation. Armed with an actual use
case, often the documentation will make sense in the context you are
approaching it from.
Similarly, when you encounter framework APIs which you have
never used before, visit the code documentation if there is any. For the
Microsoft libraries, all public methods include XML comments. You can either
read these directly or visit the .NET API Browser to
reach about a class or method.
The significant thing about consciously reading code is that
it’s your own time and that you are making an investment in your skills.
Contrast this to when you are in a codebase, up against a deadline, trying to
finish a bug fix or feature. You will rarely have the time to extend beyond the
boundaries of the code you are directly working with. That situation is much
less conducive to learning.
WHAT I HAVE LEARNED FROM READING SOURCE CODE
I’ve learned so much from studying code, which is why I’m so
enthusiastic about promoting this practice. Modern-day craftspeople will often
study the work of masters of their craft. By doing so, they hope to one day
attain their level of skill. Developers too can advance their skills by
studying from the experts in their field.
For me personally, as a C#, .NET developer, I find a lot of
value in studying the Microsoft source code for the .NET Core framework and
ASP.NET Core. There are many great developers at Microsoft who have
comprehensive expertise of specific elements of the language or runtime.
I’m a self-taught developer, or as I saw someone call it on
Twitter recently (I can’t recall who, unfortunately), a community-taught
developer. I’ve learned C# through trial and error, in concert with consciously
studying code. Just as scholars study great works of literature, there are many
secrets to be unlocked by reading great code.
One related resource I recommend for those who are intrigued
by software design and want to better their appreciation of the .NET Core
framework is available on YouTube. The .NET team publish most of their
weekly .NET Design Reviews on
YouTube. These are meetings where the team review proposals for API changes to
.NET Core. While I can appreciate that the thought of watching a meeting by
choice, in your own time may be too much geek for some, it’s a great way to
learn. The team on these calls is made up of genuine experts who know the
language, runtime and framework so profoundly, it’s quite staggering to
observe. By listening to them discuss the proposed APIs you get a genuine
appreciation for the considerations that have to be made on such a broad and
widely used framework. There are often little gems of insight I gather just by
watching these streams.
SUMMARY
My goal for this post was to inspire a few readers to
consider some more conscious study and reading of code. I honestly believe this
has helped me to become a better developer and to learn more about the C#
language and the .NET (Core) Framework. Investing a few hours regularly will
pay off for you in the future. You’ll have more diverse opinions on coding
style and techniques. You’ll understand at a deeper level how the framework you
rely on daily actually works, which in turn can inform your use of it. You’ll
become faster at reading code, and as a result, those next code changes you
have to make will take you less time from the requirement to the completed
code.
Thanks for reading!
Comments
Post a Comment