-
Notifications
You must be signed in to change notification settings - Fork 114
Reading notes & quotes
-
Hints for Computer System Design https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/acrobat-17.pdf
-
Classification and Definitions of Business Logic for End-User-Initiative Development http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=79E274E8EF8A15F443A45107BF848756?doi=10.1.1.304.4405&rep=rep1&type=pdf
-
UI-driven test-first development of interactive systems https://dl.acm.org/doi/abs/10.1145/1996461.1996515
TDD
-
Increasing Validity Through Replication: An Illustrative TDD Case
-
Attitudes, Beliefs, and Development Data Concerning Agile Software Development Practices
-
Improving Development Practices through Experimentation: an Industrial TDD Case
http://www.sensible.com/dmmt.html
All kinds of things on a Web page can make us stop and think unnecessarily. Take names, for example. Typical culprits are cute or clever names, marketing-induced names, company-specific names, and unfamiliar technical names.
As a user, I should never have to devote a millisecond of thought to whether things are clickable—or not
To do a new job, build afresh rather than complicate old programs by adding new features.
Notes: not adding all the rules, just the one that might be useful
- Rule of Modularity: Write simple parts connected by clean interfaces.
The only way to write complex software that won't fall on its face is to hold its global complexity down — to build it out of simple parts connected by well-defined interfaces, so that most problems are local and you can have some hope of upgrading a part without breaking the whole.
- Rule of Clarity: Clarity is better than cleverness.
write programs as if the most important communication they do is not to the computer that executes them but to the human beings who will read and maintain the source code in the future (including yourself).
Good Unix practice also embraces choosing your algorithms and implementations for future maintainability. Buying a small increase in performance with a large increase in the complexity and obscurity of your technique is a bad trade — not merely because complex code is more likely to harbor bugs, but also because complex code will be harder to read for future maintainers.
- Rule of Composition: Design programs to be connected with other programs.
it's wise to ask if the tricky interactive parts of your program can be segregated into one piece and the workhorse algorithms into another
- Rule of Separation: Separate policy from mechanism; separate interfaces from engines.
policy and mechanism tend to mutate on different timescales, with policy changing much faster than mechanism
- Rule of Simplicity: Design for simplicity; add complexity only where you must.
Even more often (at least in the commercial software world) excessive complexity comes from project requirements that are based on the marketing fad of the month rather than the reality of what customers want or software can actually deliver. Many a good design has been smothered under marketing's pile of “checklist features” — features that, often, no customer will ever use.
- Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do.
‘Big’ here has the sense both of large in volume of code and of internal complexity. Allowing programs to get large hurts maintainability. Because people are reluctant to throw away the visible product of lots of work, large programs invite overinvestment in approaches that are failed or suboptimal.
- Rule of Transparency: Design for visibility to make inspection and debugging easier.
Because debugging often occupies three-quarters or more of development time, work done early to ease debugging can be a very good investment. A particularly effective way to ease debugging is to design for transparency and discoverability.
A software system is transparent when you can look at it and immediately understand what it is doing and how. It is discoverable when it has facilities for monitoring and display of internal state so that your program not only functions well but can be seen to function well.
- Rule of Robustness: Robustness is the child of transparency and simplicity.
Most software is fragile and buggy because most programs are too complicated for a human brain to understand all at once. When you can't reason correctly about the guts of a program, you can't be sure it's correct, and you can't fix it if it's broken.
It follows that the way to make robust programs is to make their internals easy for human beings to reason about.
- Rule of Least Surprise: In interface design, always do the least surprising thing.
The easiest programs to use are those that demand the least new learning from the user — or, to put it another way, the easiest programs to use are those that most effectively connect to the user's pre-existing knowledge.
Therefore, avoid gratuitous novelty and excessive cleverness in interface design.
Pay attention to your expected audience. They may be end users, they may be other programmers, or they may be system administrators. What is least surprising can differ among these groups.
Pay attention to tradition. The Unix world has rather well-developed conventions about things like the format of configuration and run-control files, command-line switches, and the like. These traditions exist for a good reason: to tame the learning curve. Learn and use them.
- Rule of Silence: When a program has nothing surprising to say, it should say nothing.
Well-behaved Unix programs do their jobs unobtrusively, with a minimum of fuss and bother. Silence is golden.
- Rule of Repair: Repair what you can — but when you must fail, fail noisily and as soon as possible.
Therefore, write your software to cope with incorrect inputs and its own execution errors as gracefully as possible. But when it cannot, make it fail in a way that makes diagnosis of the problem as easy as possible.
- Rule of Optimization: Prototype before polishing. Get it working before you optimize it.
The most basic argument for prototyping first is Kernighan & Plauger's; “90% of the functionality delivered now is better than 100% of it delivered never”. Prototyping first may help keep you from investing far too much time for marginal gains.
A prematurely optimized portion of a design frequently interferes with changes that would have much higher payoffs across the whole design, so you end up with both inferior performance and excessively complex code.
get your design right with an un-optimized, slow, memory-intensive implementation before you try to tune. Then, tune systematically, looking for the places where you can buy big performance wins with the smallest possible increases in local complexity.
- Rule of Extensibility: Design for the future, because it will be here sooner than you think.
Never assume you have the final answer.
When you design code, organize it so future developers will be able to plug new functions into the architecture without having to scrap and rebuild the architecture. This rule is not a license to add features you don't yet need; it's advice to write your code so that adding features later when you do need them is easy.
You'll be there in the future too, maintaining code you may have half forgotten under the press of more recent projects. When you design for the future, the sanity you save may be your own.
http://www.lysator.liu.se/c/pikestyle.html
Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is.
Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest.
Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures.