For tips on designing a software system, I read The Mythical Man-Month. I recommend it, but here are my notes in case you just want the juicy bits:

ch1 the tar pit
a bunch of software engineering projects run over budget and schedule
 
 
ch2 the mythical man month
he estimates
1/3 time for planning
1/6 for coding
1/4 for component test and preliminary system test and debugging
1/4 for final system test and debugging
 
 
ch3 the surgical team
even a small team of really good programmers won’t be able to churn out a large system as fast as a hulking team of crappy programmers
 
there are combinatorial costs as you increase team size, due to all the communication that has to be done between subsets of members. you can solve this by making specialized teams supporting one star–to minimize communication–rather than making teams of equals who all have to talk and argue
 
 
ch4 aristocracy, democracy, and system design
have a few architects design–the builders will get to be creative in satisfying that design, even if they miss out on the fun of initially architecting it, and the product will be better as a result of having that cohesive design by a small group than it would’ve been if done democratically
 
 
ch5 the second-system effect
the first system you design is necessarily simple and clean because you need to get it out the door. so you make notes of all the neato features you’d want to have if you had more time. and those make it into your second system. but you already know they were unnecessary because you built the first one without them, and even worse, they may have been made obsolete by a basic difference between this second system and the first, which generated these feature-ideas. so watch out buddy
 
 
ch6 passing the word
decide what parts of your spec are just undefined
 
making two implementations is a good way to ensure the spec is followed, rather than changed to match the implementation
 
when an implementer has a question, he must ask the architect, and the architect should record these questions and answers and disseminate them to all implementers
 
 
ch7 why did the Tower of Babel fail?
the OS/360 project kept a daily-updated workbook that contained all the specifications. but the workbooks couldn’t just be updated silently, there needed to be a changelog describing the updates, and the updates needed to be marked (this sounds very familiar…)
 
 
ch8 calling the shot
in estimates, you must budget time for stuff that’s totally unrelated to coding and debugging: interruptions, meetings, …
 
there are some conclusions drawn here from thin data… i don’t trust ’em
 
 
ch9 ten pounds in a five-pound sack
when your code can trade off space and time, make two versions: one that’s light on space and one that’s light on time, then use the appropriate ones
 
 
ch10 the documentary hypothesis
writing out your ideas and estimates and budget, … forces you to make a ton of small decisions that are essential, so do it.
 
 
ch11 plan to throw one away
think of the first system you build as an instructive exercise that teaches you what you actually need to build, then build that new thing.
 
 
ch12 sharp tools
they used to automatically schedule (scarce) machine time in 4-hour chunks–so you’d submit a job and it would get scheduled and run, then you’d get the results and could try again if it failed. but they found it was way more effective to just give a whole team unlimited access to the machines for 6-hours in which they could run as many jobs as they needed. that way if your first job failed immediately you could just fix it and start a new one.
 
let developers build their components freely, but when ready to drop into the system, they give that version to the integration manager who is the only one with the power to allow changes to it. after testing the integrated system, that version of the codebase can be released
 
build tools to test the performance of your system automatically
 
use high-level languages (he likes PL/I for system programming, with APL to prototype algorithms) and interactive programming environments
 
 
ch13 the whole and the parts
designing top-down will help you to dodge bugs that result from poor specification
 
test your components well and individually–even though it’s tempting to use one component to test that another works
 
don’t throw stuff together and start system testing until you’ve done component (unit) testing
 
 
ch14 hatching a catastrophe
prefer specific, well-defined milestones to ones that are more vague but easier for outsiders to understand
 
when a component gets behind schedule, its manager doesn’t want to tell his boss, because the boss might step in. but the boss needs to know this stuff, so if you’re the boss, don’t step in when the manager can solve the problem–you want to know this stuff so don’t give the manager a reason to hide it from you.
 
lay out your milestones in a chart showing their dependencies (like a PERT chart), and regularly review your progress through that chart
 
 
ch15 the other face
document your code.
 
describe the program at a high level, in prose–you should probably do this before you even code it
 
you probably don’t need to make flow charts, and definitely don’t make a flow chart that’s bigger than 1 page
 
put yor documentation in the same file as your code
 
make more paragraph-length comments and fewer single-line comments
 
document as you go
 
 
ch16 no silver bullet-essence and accident in software engineering
it’s hard to visualize a piece of software–there are too many dimensions of stuff going on
 
big software systems are too complicated to fully specify up-front–instead, rapidly prototype the system, then figure out the details
 
grow your software system bit-by-bit so you have working versions all along the way–don’t set out to build it through incremental progress toward a grand goal
 
 
ch17 no silver bullet refired
not much content here
 
 
ch18 propositions of the mythical man-month true or false?
this chapter is a big outline of the whole book with references to current data. i skipped this because i was more interested in his personal experience than in research on software engineering, which i tend to find questionable. how generalizable are the results of analyzing one software engineering project going to be when the studies are purely historical and don’t include experimental manipulation? how comparable are lines of code statistics between projects? how interesting is lines of code as a summary statistic anyway?