| Well, first we should establish what we mean by "quality code". From my standpoint, both as an engineer and as a manager, quality means that the code: (1) Does what it is supposed to do and nothing more; (2) Is easy to read; (3) Is easy to change; (4) Is efficient enough. Note that these points are somewhat strongly ordered. If you have to make a trade-off between "maximal efficiency" or "can be read by the rest of the team", you choose readability, unless "maximal efficiency" is required to meet a customer deliverable ("acceptance criteria"). Note the word "required". As in, "we have promised our customers to service requests in under 2ms, and these rather unreadable performance optimizations are the only way we can do this", not "the lead programmer likes 'efficient' code". That's not to say you should be stupid about performance -- see (4), above -- but that your goal is to deliver value to the customer, not to build a technical monument to Donald Knuth. That prompts the next thing we need to talk about: what do we even mean by "high velocity"? Clearly it isn't just writing a lot of code. Were that the case, we could measure productivity in LOC/day. And it isn't in always using the minimum amount of memory or smallest number of CPU cycles. From a business perspective, "high velocity" means "delivering working features to our customers as fast as possible... forever". That last bit is important. You aren't going to get one feature request, scratch that off in a frantic 48-hour marathon of caffeine and hackery, and then be done with the rest of your career. New feature requests, changes to existing features, unexpected behavior that needs to be changed... these are life as a programmer. Smart programmers recognize this, and build their code to be easily changed. Now, you can't do this by trying to anticipate every future need. Building code to support an uncertain future is where the vast majority of technical debt comes from, because 90% of the time, you'll just be flat-out wrong, either grossly, or in sufficient detail as to render your attempt to defend against change moot. Instead, you follow a set of coding practices that help you design systems and build code that can respond to future change, without having to know anything about what those future requirements might be. To that end, I highly recommend Sandi Metz's POODR[1] and 99 Bottles of OOP[2]. Yes, the title of the first book ends in "Ruby". Ignore that part, as it's probably the best primer I have ever seen on building code for the real world. I have also found that strong TDD -- and yes, I'm lumping BDD in with this, don't be a pedant -- has helped me to learn to write much higher-quality code over the years. Code that is fully-tested can be changed with a high degree of confidence that you haven't broken something unintentionally, and writing tests first forces a lot of highly beneficial design choices. GOOSGT[4] is a good place to get started with TDD. Last but not least, recognize that all of the above are skills -- you will need to devote time, and a lot of repetition to learning them. [1] https://www.poodr.com
[2] https://www.sandimetz.com/99bottles
[3] http://www.growing-object-oriented-software.com |
As for feedback I typically start the feedback cycle very early on so there are no surprises at PR time and remember that it's all about the knowledge creation not proving how great one is as a coder per se in other words get in the habit of asking "how would you code this?" to the person eventually looking at your PR
Even if one's implementation is rejected one's tests are still valuable, no?
I usually code in some variation of TDD or BDD where tests serve as a framework for refactoring and we iteratively improve our implementation while increasing our confidence that the solution actually fits the requirements
Here is my ten rules of coding in the spirit of Elmore Leonard
- naming is hard it's also the most important task take inspiration from the watch repair channel a name for everything and everything with a name coding is 99% naming and 1% organizing - never name anything "SomethingManager" it's an anti pattern and shows you have no idea what to name the thing - Code is twice as hard to read as it is to write - all writing is rewriting i.e. all factoring is refactoring - vulnerability means giving it your all i.e. aim to be a 100% coder who gives it their all rather than a 10x coder who bests the field - Never forget people used to do this stuff on punch cards and the first bug was a real insect also never forget people would kill for a chance to fill your shoes - dressing up for work shows you treat your role with dignity greater than just yourself and still matters if only as a nod to the originals like Alan Turing and Charles Babbage - if you only read one book read POODR - avoid silos like the plague a team only succeeds if everyone succeeds and knowledge workers are meant to spread the knowledge - remember Conway's lesser known second principle software is as fun to use as it was to write
That and hang in there for the rest of us we're here for you too
To the downvote brigade if you find my sentiments not to your liking how about an upvote for visibility with a snarky comment rather than an anonymous downvote?