
Ask HN: How best to learn software design principles? - chaimkut
Recently I had several rounds of interviews with one of the big tech companies, and while they said my problem solving and coding skills were good, they said they eventually decided to reject me due to my inadequate solutions to design problems, particularly software design.<p>In the long term, I&#x27;m sure the usual advice of reading through great open source code is the way to go. In the short term, where can I find write-ups of software design, going from &#x27;How would you build a spreadsheet program?&#x27; to actual UML designs, discussion of design patterns, etc.
======
pessimizer
[http://www.aosabook.org/en/](http://www.aosabook.org/en/)

"Architects look at thousands of buildings during their training, and study
critiques of those buildings written by masters. In contrast, most software
developers only ever get to know a handful of large programs well—usually
programs they wrote themselves—and never study the great programs of history.
As a result, they repeat one another's mistakes rather than building on one
another's successes.

"Our goal is to change that. In these two books, the authors of four dozen
open source applications explain how their software is structured, and why.
What are each program's major components? How do they interact? And what did
their builders learn during their development? In answering these questions,
the contributors to these books provide unique insights into how they think.

"If you are a junior developer, and want to learn how your more experienced
colleagues think, these books are the place to start. If you are an
intermediate or senior developer, and want to see how your peers have solved
hard design problems, these books can help you too."

edit: a major advantage to aosa is that all the source is available.

~~~
nikhilalmeida
[https://github.com/aosabook/500lines](https://github.com/aosabook/500lines)
This is a repo of smaller real world applications that are 500 lines or less
in length, so as not to be overwhelming to novice / intermediate programmers.

~~~
svankie
Hey, thank you!

------
laurenbee
Bob Nystrom's _Game Programming Patterns_ is an engaging, informative book
about design patterns that are commonly used in games but are relevant to non-
game software too.

[http://gameprogrammingpatterns.com/](http://gameprogrammingpatterns.com/)

~~~
squeaky-clean
I love this book. It's a good introduction to design patterns. Very well-
written and entertaining, and filled with real code examples. It's certainly
not boring, I was able to read it in about a weekend (and I read slowly). For
a free book, that's such a quick read, it has a surprising amount of knowledge
in it.

------
simplify
Learning software design principles is like learning how to draw - you need to
study many, many examples before getting a good feel for it. For example, in
drawing there are many individual principles, such as shading, perspective,
scale, and so on. Studying each individual principle is only useful _within
the context of a full drawing_.

Software is the same way. Studying SOLID principles, application boundaries,
encapsulation, etc. only makes sense _within the context of a working
application_. Not only that, but making sense of design decisions is not as
easy as "seeing the result" like you can in a drawing. With software design,
you have to take a step further and continuously ask questions:

    
    
        "Why?"
        "Why not this?"
        "When would I use this?"
        "When would I *not* use this?"
    

I'm an instructor at a coding school[1], and one of our biggest goals is to
inculcate software design principles into our students. Frameworks are useful,
but if you never learn proper software design, you'll always be stuck as a
_framework_ developer (e.g. Rails/Angular developer), and never become a
_software_ developer (i.e. frameworks and languages are just details).

[1] [http://www.makersquare.com/](http://www.makersquare.com/)

~~~
mattgreenrocks
The difference between framework and software developer is often glossed over
by people, especially on HN. In the position of the former, you're pushed
around by your tools. In the latter, you learn how to push back and impose
structure that speed development, clarify thinking, and reduce bug counts
dramatically.

~~~
collyw
You are implying that rolling your own will give you faster, less buggy code,
more organised code than using a framework?

------
mattgreenrocks
Don't feel too bad; the pop culture side of programming (a lot of HN) is
profoundly anti-design of any type. This is likely a reaction to perceived
overdesign of years past, such as in Enterprise Java. Thus, you don't see as
many articles about the topic. (I also sense a bit of nerd-indignation over
the fact that this is a squishy subject and nobody's completely right).

Read the AOSA book, read Design Patterns, and read something like Domain-
Driven Design. Realize that no-architecture is frequently chosen due to
ignorance ('pragmatism'). Know SOLID back and forth. Understand why people
strive to isolate things when doing TDD. Recognize and know how to decrease
coupling, and what the costs of that are. You can practice these concepts
every day, and you should, if only to develop the necessary element of taste.

You'll go through a phase where you adhere to these ideas religiously, then
eventually assimilate the knowledge so that it becomes almost unconscious.

Best of luck.

~~~
napoleond
_Don 't feel too bad; the pop culture side of programming (a lot of HN) is
profoundly anti-design of any type._

I think that's a surprising characterization; it doesn't jive with my own
perception (as subjective as that may be). I think the past decade has
(rightly or wrongly) seen a reaction in our industry against enterprise-style
"architecture astronauts" but that doesn't equate to being "anti-design". (I'm
thinking of the emergence of Rails-like frameworks vs. the JEE stack, and then
the emergence of micro-frameworks like Flask/Express/Sinatra after that.)
Simple/reduced structure is a valid design choice (of course there are trade-
offs that come with that, and of course they aren't always appropriate, but I
don't think that means it's popular to be "anti-design").

~~~
jalfresi
" but that doesn't equate to being "anti-design"

I agree fully. I feel that the shift has come about because there has been an
unconscious recognition that restricting your tools to one particular problem
domain is a valid constraint to make on a design. Enterprise scale,
"architecture astronauts" and the like were trying to build tools with which
you could build anything, for anyone. And it's clear from the results that
this is just a vector for complexity to creep in. Focused tools, from libs to
frameworks unashamedly limit themselves to one particular problem domain, or
at least used to.

I've certainly noticed a shift in that these hard learnt lessons are being
ignored in order to add features to frameworks etc; which increase their
applicable scope, with the increase in complexity that arises. The primary
driver of which appears to be the younger generations desire to use the same
tools for different purposes rather than learn a new set of applicable tools
for a different problem domain. A good example is the shift from v1 Zend
Framework to Zend Framework 2 which just appears to be so heavily
"Java/Enterprise" influenced I simply refuse to use it; its far far too
complex a framework for what is essentially a framework for building web
sites. Building web sites is simple. These modern frameworks make it massively
more complex than it needs to be.

------
rubiquity
Learn a functional programming language. This has had the most impact on the
way I think about systems by far. The biggest impact was realizing all of the
time I've spent trying to master all of the OOP acronyms hasn't paid off. I've
also realized that OOP might be meant for a type of programming that I don't
do (video game logic? device drivers?), where as FP seems to fit great for Web
applications that are just wrapping databases and spitting out HTML or JSON.

As for FP languages for a starter, I'd recommend any of Erlang/Elixir, Clojure
or Scala (only for its FP features and great learning resources)

~~~
prometheuspk
Would you say that FP itself (not the thought process it generates) would
benefit me in mobile application devlopment. It's mostly gaining data and then
setting it.

~~~
platz
FP has been hard to realize on mobile mostly due to the limited choice of
languages available.

~~~
rubiquity
Yeah, I agree with this. However, I could still see a lot of merit in writing
the server that the mobile application talks to in an FP language.

------
mtdewcmu
What they want is mainstream orthodoxy like Design Patterns, OOP, etc. You'll
want to study the buzzwords, mostly. What are the major principles of OOP?
What is a Decorator Pattern? What is TDD?

You won't be able to infer this stuff from studying software that works well.
There are specific words they want to hear. Functional programming is probably
not going to help at those interviews. FP isn't used at big corporations.

~~~
dropit_sphere
Unfortunately, this is very likely the case. Do all the things the thread
suggests to learn about design. Then go read the Gang of Four book to get a
job.

~~~
mtdewcmu
I'd get a job first. If you are not enthusiastic about corporate programming,
there are all kinds of companies with all different styles. If you look hard
enough, you can find one that fits your style.

------
seregine
The book that inspired software patterns. I found it more interesting than
GoF's "Design Patterns", and it feels less dated these days: The Timeless Way
of Building by Christopher Alexander
[http://en.wikipedia.org/wiki/The_Timeless_Way_of_Building](http://en.wikipedia.org/wiki/The_Timeless_Way_of_Building)

The C2 wiki has interesting entries on software patterns and related ideas:
[http://c2.com/cgi/wiki?WikiPagesAboutWhatArePatterns](http://c2.com/cgi/wiki?WikiPagesAboutWhatArePatterns)

Stanford CS 240 has a great list of papers on system design:
[http://web.stanford.edu/class/cs240/](http://web.stanford.edu/class/cs240/)

One paper that's no longer on that list, but I remember from when I took the
class: End-to-end arguments in system design
[http://web.mit.edu/Saltzer/www/publications/endtoend/endtoen...](http://web.mit.edu/Saltzer/www/publications/endtoend/endtoend.pdf)

~~~
jalfresi
Another good one by the same author Christopher Alexander is "Notes on the
synthesis of form", my all time favorite book

------
presty
People in this thread are generally telling you to either read a book or build
something, when those things are not mutually exclusive.

So read books, build things and read code.

I like to dig into open source libraries/frameworks/tools that I use in my
projects and try and understand their design. It would be great if the
documentation people write focused a little on that, instead of the more
common "this is how you install" and "this is how you use" (and sometimes
"this is how you build it") - but writing docs is hard/tiring and so that
knowledge gets lost.

------
halayli
* The C++ Programming Language 3rd edition, Part IV of the book.

* Large-Scale C++ Software Design

* The Practice of Programming

* Code Complete

These are a good start but in the end it's experience. It takes a lot of
practice to build a good intuition when making software design decisions.

~~~
mattgreenrocks
Large Scale C++ Software Design is a real gem.

~~~
halayli
Yup. The author obviously have seen it all.

------
kushti
The #1 book is "Design Patterns: Elements of Reusable Object-Oriented
Software" by Gamma/ Helm / Johnson / Vlissides. It's about imperative
programming though, functional/hybrid languages have other design patterns(but
"Design Patterns" is #1 anyway).

\+ Free Book "The Architecture of Open Source Applications" :
[http://hackershelf.com/book/54/the-architecture-of-open-
sour...](http://hackershelf.com/book/54/the-architecture-of-open-source-
applications/)

------
shrig94
I think one of the most helpful classes at MIT for learning the basics of
software design is 6.033. Class schedule and readings here:
[http://web.mit.edu/6.033/www/schedule.shtml](http://web.mit.edu/6.033/www/schedule.shtml)

In particular, the papers covered topics of software design from failures
(like Therac-25) to examples of successfully designed large scale systems
(like Map Reduce). I'd highly recommend reading through the papers, most of
which can be found via Google search.

------
craigching
I'm going to go out on a limb here and not recommend a book. Good architecture
and design take _practice_. You can get that practice by working with someone
who understands it (some of the better, larger open source projects might be a
good way to go).

Books can help to a certain degree, but you have to make a conscious effort to
practice what you're reading. The best thing to do, assuming you can't get the
experience on the job, would be to find a _big_ project and understand and
contribute.

~~~
ams6110
I'm not sure it follows that a big project is necessarily an example of good
design. But agree on the point that you can't just read about it. Having a
qualified mentor is great; if you don't, read _and_ practice.

Note that a lot (most?) comp sci programs don't necessarily address design
principles. If you're in a software engineering track they should, but my
curriculum was mostly algorithms, data structures, operating systems, and
programming languages. My senior year I had one class where design and project
management was really a topic.

------
bigtunacan
I've seen multiple people mention the GoF's Design Patterns book. This is well
known and worth several reads through; it will take multiple passes to grok
all of it.

There are several other books that have tried to explain the GoF's Design
Patterns in either an easier to approach manner, or in the context of a
specific language they have tried to explain where new design patterns have
emerged or the original patterns had mutated.

A couple of those worth checking out are

"Head First Design Patterns"

[http://www.amazon.com/Head-First-Design-Patterns-
Freeman/dp/...](http://www.amazon.com/Head-First-Design-Patterns-
Freeman/dp/0596007124/ref=sr_1_1?s=books&ie=UTF8&qid=1404810991&sr=1-1&keywords=head+first+design+patterns)

"Design Patterns In Ruby"

[http://www.amazon.com/Design-Patterns-Ruby-Russ-
Olsen/dp/032...](http://www.amazon.com/Design-Patterns-Ruby-Russ-
Olsen/dp/0321490452/ref=sr_1_1?s=books&ie=UTF8&qid=1404811054&sr=1-1&keywords=ruby+design+patterns)

"Learning JavaScript Design Patterns"

[http://www.amazon.com/Learning-JavaScript-Design-Patterns-
Os...](http://www.amazon.com/Learning-JavaScript-Design-Patterns-
Osmani/dp/1449331815/ref=sr_1_1?s=books&ie=UTF8&qid=1404811139&sr=1-1&keywords=javascript+design+patterns)

------
seanewest
I sincerely believe that programming has gone through a couple of paradigms
over the decades. For instance it used to be a good thing to never be scared
of architecting a solution from the ground up (and the best often did) whereas
nowadays our ecosystem of libraries and tools are so vast that it much more
often is overkill, and the architect mentality often a handicap. (This is
obviously just one person's opinion)

Sounds principles are sometimes tied to these paradigms. For instance in past
years one could maybe say "never use a tool that you don't know well" whereas
nowadays with all of the layers of technologies that you are forced to work
with it may have changed to just knowing why you have to use a technology and
knowing well the aspects that you are using it for.

Also, there are by now many generations of programmers, and we might not want
to admit it but the people that grew up on assembly do tend to have different
sensibilities than the people that grew up on scripting languages. With these
generations often come ingrained mentalities that are tied to paradigms that
are tied to principles which in fact are still subject to change.

------
tzaman
[http://cleancoders.com/](http://cleancoders.com/) See them all. The best
investment you can make into yourself.

~~~
valarauca1
I hate to sound stingy but at $445 is there a cheaper alternative? Like a
book, or maybe shorter series?

What videos would prioritize over the others?

~~~
tzaman
Well $445 is nothing in contrast to what you can make if all this knowledge is
put into effect. I would definitely recommend SOLID principles above others.

~~~
ivanche
It depends heavily on your place of living. In my country $445 is about or
over the monthly salary for vast majority of people.

~~~
tzaman
Well yes, $445 can relatively be a lot of money, however, in times of
globalisation and developers being in high demand one just has to think
outside the box a bit and join a company remotely if possible. I'm not saying
it's easy, but can be done.

------
antocv
While I agree that many of the already given examples of books to read are
really good books, nice reads.

I feel the best way to get into the mindset of good design, or design
principals - even if it isnt "examples of good design" as the AOSA book - is
to get immersed into an architecture formed from a design based mindset
different than what you are used to.

Learn something engineered with design principles heavily visible in mind.
What is the design principle of a modern GNU/Linux system? Its mosthly
philosophical, you wont find the answer in several books, its spread out far
and wide and requires that you actually use GNU/Linux for years, to have taken
part in its history.

I suggest you pick up and learn JSF (Java Server Faces). Start reading JSF
books, Java Enterprise things, start coding it, doing it. One good book is JSF
in Action from Manning I believe.

When you begin reading about or trying to make a hello world site in JSF -
youll be like "wtf is this, fuck" \- thats right - thats you being exposed to
a different design principles based mindset. Its not bad, its in fact very
good (JSF and the experience).

Only once youve finished say a "community website, friends can befriend each
other, send messages, write on wall, share pictures." in JSF, even though it
looks as ugly as can be - then youve advanced more in passing those interviews
with regards to design principles - than reading any of the books mentioned so
far in this thread. But reading the other books wont dis-help you.

EDIT: From experience, the books flaunted around here, Code Complete, AOSA,
Design Patterns here there and everywhere, are just bullshit for this task.
What your interviewers were asking for is not if you can count and use Design
Patterns. Or if you agree or dont agree on which method in a class should be
refactored out and what it should be named. Dive deeper out of your comfort
zone - go for JSF.

------
chton
Dive into design patterns. Get yourself a good book listing them. The bible of
all developers is the Gang Of Four ([http://www.amazon.com/Design-Patterns-
Elements-Reusable-Obje...](http://www.amazon.com/Design-Patterns-Elements-
Reusable-Object-Oriented/dp/0201633612)), but there are plenty good ones out
there that aren't as dry and academic.

Design patterns are the greatest tool there is for learning software design.
If you know them, you can apply them, but much more importantly they show you
how you can apply the basic principles of OO development to various problems.
By learning them, you're learning the thought process of how they came to be,
and you'll be able to apply those thought processes to your own problems.
Consider it like learning algebra by doing exercises. You can read theory all
you like, but unless you apply it it just won't click.

------
skanuj
[http://www.objectmentor.com/resources/publishedArticles.html](http://www.objectmentor.com/resources/publishedArticles.html)
See Design principles before Design patterns.

[http://martinfowler.com/design.html](http://martinfowler.com/design.html) is
also good.

------
philrea
Write a relatively complex system without any external code and, preferably,
without any previous training...

It will suck, it will break, and eventually, it will be near impossible to add
or change anything at all. But you will have experienced what the patterns n'
principles authors (better) have and, I bet, even "accidentally" used a few of
them.

In my opinion, design principle = minimize dependency. Oh and, if you do
follow my suggestion, use a language that isn't object oriented... at the
least you will, like me, wonder why "object-oriented something" isn't
explicitly defined by gof elsewhere and, at better, might "accidentally"
implement some sort of custom object system

I am gonna go ahead and say it... REINVENTING THE WHEEL IS A GOOD AND
NECESSARY THING... if done for the right reasons, in the right
circumstances...

------
edderly
When I interview someone about design problems, I'm most interested in their
approach to decomposing the problem and their ability to express their
thoughts and keep a track of their ideas as well as interact with me.

In a way, you're almost looking at the interviewee as a teacher except they're
obviously having to improvise on the subject at hand.

I'd suggest the best practice is to understand the structure of software
you're interested in and write about it.

------
tegeek
When it comes to designing large scale business systems, I read Application
Architecture Guide. I read every chapter many times and then eventually got
enlightenment.

Here is the detail description and PDF book [http://msdn.microsoft.com/en-
us/library/ff650706.aspx](http://msdn.microsoft.com/en-
us/library/ff650706.aspx)

It is targeted towards .NET developers but equally good for JVM, NodeJS etc.

------
mikevm
I would consider looking at the following books:

[http://www.amazon.com/Beginning-Java-Objects-Concepts-
Editio...](http://www.amazon.com/Beginning-Java-Objects-Concepts-
Edition/dp/1590594576)

[http://www.amazon.com/Program-Development-Java-
Specification...](http://www.amazon.com/Program-Development-Java-
Specification-Object-Oriented/dp/0201657686)

------
iqbaljamsheed
I'm currently 16 year old, studying in middle school. I want to enter
programming, and am already taking Codeacademy courses in Javascript.

I want advice from experienced programmers, on programming, and generally
becoming a good programmer and how to think like a programmer.

I also want suggestions for resource that I can use at my absolutely beginner
level

Thanks

------
kazinator
This simply looks as if the jobs you're applying for are too senior for your
level of experience. Or the interviewers are idiots: they are looking for an
ordinary developer, but interviewing for an architect. (This was a recently
posted HN topic.)

Get a job that's right for you and use it to get the design experience.

------
tjr
You might find one of these interesting:

[http://philip.greenspun.com/seia/](http://philip.greenspun.com/seia/)

[http://www.amazon.com/Software-Architecture-Primer-John-
Reek...](http://www.amazon.com/Software-Architecture-Primer-John-
Reekie/dp/0646458418/)

------
senderista
From 1983, could have been written yesterday (immutability, log as source of
truth, etcetera):

[http://research.microsoft.com/en-
us/um/people/blampson/33-hi...](http://research.microsoft.com/en-
us/um/people/blampson/33-hints/WebPage.html)

------
sidcool
I feel for you. I was rejected from ThoughtWorks for this exactly same reason.
I received a coding assignment and I implemented it. The solution worked, but
it was not Object Oriented enough, nor was it easy to maintain and flexible.
Thanks for asking this!

------
ap22213
Are you able to elaborate on some of the types of design problems that they
threw at you?

------
mck-
Engineering Long Lasting Software [1] is a book written by UC Berkeley profs
who were teaching a great SaaS-class on Coursera (using Rails) two years ago

[1] [http://www.saasbook.info/](http://www.saasbook.info/)

------
brodo
I really like the SOLID principles:
[https://sites.google.com/site/unclebobconsultingllc/getting-...](https://sites.google.com/site/unclebobconsultingllc/getting-
a-solid-start)

------
arikrak
I also was wondering if there was a good way to learn and practice this topic.
There are many ways to do smaller coding challenges, but how do you practice
software design without having an actual expert to talk to?

------
username42
Teach them. Whatever the subject, when you have to teach it to someone, your
level of understanding increase. If you can find a public ready to listen to
you, teach the subjects you want to master.

------
tpae
Try this:
[http://addyosmani.com/resources/essentialjsdesignpatterns/bo...](http://addyosmani.com/resources/essentialjsdesignpatterns/book/)

------
thruflo
The books referenced in this thread are no doubt great but I wouldn't read a
book to get better at software design. I would design software.

------
peq
[http://principles-wiki.net/](http://principles-wiki.net/)

A wiki with some nice explanations of design principles.

------
weishigoname
reading software design principles book is just one thing, most important
thing is find a good way to practice what you learned from book, I suggest you
following a open software project, or create your own, when your project
become bigger, you will face more challenge, and you will learn more. :) just
for your reference, fix me if you have better idea

------
braydenjw
I see a lot of people suggesting books on design patterns.

