The book I wish I'd started from is How To Design Programs. While it uses a dialect of Lisp, Racket, the key ideas are applicable to all programing langues.
Essentially, it encourages designers of anything to "think before you ink". In the case of software, first write a "Signature, Purpose Statement, Header" which expands to: State what kind of data the desired function consumes and produces. Formulate a concise answer to the question what the function computes. Define a stub that lives up to the signature.
The book stresses test-first development, writing failing tests using stubs and then getting them to work. I find the discipline of this results in far better code, and the examples created by the tests help a lot when refactoring later.
A reason I wished I'd started with that book is that it's a difficult habit to develop later. Nowadays, using mainly JavaScript, I've come to rely a lot on JSDoc for documentation and Jasmine for testing, neither are ideal, but I can't find anything better.
My theory of why Unix took over the world was that it was slipped into a contract to supply a documentation system to the patent office, resulting in man pages as a side-effect, yielding documented applications which seems to still be a revolutionary idea among coders.