
Ask HN: How do you guys approach abstractions when reading code? - grosales
I have been going through code, as far as I can tell the code is very hard to read. It seems that all the abstractions put in place for (future) flexibility make it so. Sometimes when I am reading code I end up in a place, and I have to backtrack to realize how I got there. I had to basically write down every step of execution to figure out how everything fit together.<p>This put me to think that sometimes abstractions can lead to very hard-to-navigate code. Is this usually the case? or did the architects blew it? This code is written in an OOP language btw (Java).<p>Do you guys think that sometimes code can get unnecessarily complex, if so do you guys have any war stories or advice to avoid going down that path? How do you guys approach abstractions to make it as leakage proof as possible? And finally, how do you guys read complex code? I am used to reading code, every once in a while I go through some open source code and try to figure out how it works, but If there is a book you guys could recommend to get better at it, please do.<p>Thanks
======
sophacles
When I first started coding, both reading it and writing it, I found that a
lot of people wrote code in an unnecessarily complex way. Then I would decide
to code it in the much simpler way I saw in my head. As I coded along, trying
to add the features I needed, I would see a way to be even more flexible for
only a little cost. Frequently I would go back and look at the "ridiculously
complex" code, only to find that our implementations were similar after all.
My understanding of the problem was much more sophisticated tho.

This happened frequently, but in retrospect, as I practiced this more, I found
that I was discovering the similarities between my solution and the already
existing code much sooner. Eventually I learned to trust the other developers,
that they had a more sophisticated understanding of the problem than I did. I
also learned about refactoring and how that affects code shape (going through
a similar process to that mentioned above).

Other times when I find reading the code to be a problem, it is due to "future
flexibility". Sometimes this is needed, others it is a waste. One thing to
keep in mind tho, is that the "future" represented in the code may have
already passed. I have some code I am frequently accused of "prematurely
future-proofing", however in reality the changes the code was handled to
design are now mostly incorporated. At the time the future-proofing was done
however, life was hectic and "must do" changes were coming down the pipe daily
and the flexibility paid off.

Finally, there is the option that its crap code. I and most others have
written plenty of that too. One thing that helps me in that case is to stop
trying to figure out the code as a whole. Instead I refactor it as I go, since
well factored code can lead to a big decrease in cognitive load.

Best luck.

------
ieatpaste
Personally, I have little trust in documentation. Not that it's useless, but
that documentation rarely holds everything you need to know about the code.
Usually, I'll take a high-to-low level approach, and use visualization
programs/plugins which graph the class dependencies and overall structure.
I'll take a look at the Jdoc/similar for class/function definitions, and then
look at the run a debugger and look at the stack to see the flow of functions.
This strategy works well for 99% of cases.

Though planning ahead is good, sometimes the extra, non-implemented features
are dead weight until finished. I would recommend designing for expansion
structure-wise, but working on just the immediate changes. This way it makes
the code easier to read, and simpler (relatively speaking).

I'd like to know people's opinions for performance vs ease-of-
readability/ease-of-extensibility. Personally, I find that when the code I've
written is too complex, then the code probably isn't very good. In that case,
I'll rewrite if the architecture is off, or just refactor to make it
prettier/more extensible, even at the cost of a little performance.

------
ivanstojic
I've always been pretty good at reading other people's code. As a
developer/consultant I switch codebases often, and I agree with the other
poster about reading code making you good at reading code.

My approach is somewhat different than others mentioned here. I do take the
top-down approach, but in a limited depth first mode. I will usually start
with the code's entry point and drill into each section, one at a time.
However, I rarely drill down to the bottom of each section on the first run
through. I guess I have an abstraction filter that intuitively stops me when I
feel that I'm passing from "what's going on" to the "how it's being done"
level.

At certain points during getting to know the code, I will restart from the
entry point, drilling deeper into subsections that I now feel are becoming
more relevant to my understanding.

After a while I switch from the linear scanning into a mode more like random
access, where I pick up classes by name or package depending on what I'm
trying to understand better, and working my way up the call stack until I
reach parts of code that I've already understood.

All of this is done statically, ie. by walking through the code in an editor.
I rarely step through the code in a debugger. This is mostly because two
reasons: I have faith that I can hold a large call stack in my head and I
believe I can jump around in the call stack in an editor faster than I could
with a debugger. My faith in my brains is possibly misplaced, and has at times
failed me. My aversion towards debuggers comes pretty much from the early
nineties where building/running was often very slow and one had to get a feel
for the code before a debugger became really useful.

I'm sure there isn't only one way to do it, this is just how I do it. I hope
it helps you in your endeavors!

------
darkxanthos
It also matters how hard they try to make it readable. Here's an example of
some tests for an OSS project I'm working on (It's a messaging application).

[http://github.com/jcbozonier/alloy/blob/d8dfbd51285c6c83df78...](http://github.com/jcbozonier/alloy/blob/d8dfbd51285c6c83df783c0eac112742ab134d22/IronTwit/Alloy/Alloy.Specs/sending_message_specs/Sending_a_message_in_general.cs)

------
tirrellp
You get better at code by reading code.

That being said, I have NEVER been good at pouring through lines of code to
figure out whats going on. Others seem to be exceedingly good at it. The
closest analogy that comes to mind is music. Some can read music really well
and play from sheet music, others play by ear or by 'picking apart' a song. I
have always had to step through with a debugger and/or read the documentation
(if it exists) to get a sense of what is going on.

I guess thats why I comment my own code so much, because at the time I am
creating it and living in it day to day, I know exactly whats going on... its
"in my head" so to speak, but if i take a few weeks off, I am cursing myself
for not having commented what was going on, or at least the _intent_ ,
especially for the hairy/unfinished/broken parts.

There are some who dont comment because they are so good at reading code, they
dont even think about it. There are still others who say, "If a fellow coder
cant figure out whats going on by looking at the code and ONLY the code, then
(s)he sucks", and another camp who want to comment every single line. YMMV on
that one. To each his own, but I am in favor of a reasonable level of
commenting.

Bringing my point back from the brink, here is an story for you: In my 9 to 5
(project manager), I do very little coding anymore, but we always talk about
stuff like agility and customer centricity. There was an issue with my team
where half the people thought comments were superflous and the other half
wanted to see more comments as part of 'sound engineering practices.' As the
unbiased outsider, I told the team this, "We talk about reacting to customers
needs and putting in features, fixing bugs, increasing usability, better user
documentation, etc to meet that goal. You should consider your team mates as
customers, and you have an unmet customer need in that you have a customer who
is asking for more code comments. In the end, if it helps the team work better
together, then the 5 minutes you take to at least comment the 'intent' or
'high level algorithm' of a method will go a long way when 3 years from now
some intern is trying to figure out where the null pointer is coming from.

From the standpoint of open source projects, documentation is something I see
popup a lot on sourceforge when projects are looking for help. However, if a
person is good enough at reading code with no comments to gain an
understanding and write the documentation, they would probably much rather
code up a new feature than comment/document.

Code almost always runs the risk of becoming unecessarily complex, and there
is always a balance to be struck between YAGNI and 'flexible architecture'. I
like to lean in the direction of YAGNI, because most often the assumptions you
made about future state to build in flexibility were WRONG, and its a lot
easier to refactor for the present than it is to architect 'for the future'

