惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
C
Check Point Blog
J
Java Code Geeks
腾讯CDC
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 三生石上(FineUI控件)
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
Engineering at Meta
Engineering at Meta
罗磊的独立博客
Last Week in AI
Last Week in AI
B
Blog
IT之家
IT之家
S
SegmentFault 最新的问题
D
DataBreaches.Net
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
博客园 - 聂微东
U
Unit 42
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
MyScale Blog
MyScale Blog

Secret Weblog

Becoming More Xee: A Modern XPath and XSLT Engine in Rust Looking for new challenges! Repeat Yourself, A Bit The Curious Case of Quentell The Humble For Loop in Rust The Humble For Loop in JavaScript Don Question Best Practices I Was a 1980s Teenage Programmer Part 5: Achieving Assembly I Was a 1980s Teenage Programmer Part 4: The Call of Assembly The Tooling Shift I Was a 1980s Teenage Programmer Part 3: MSX-2 JavaScript: when you need two ways to do it! Empowering Programming Languages Bloat and Retrofuturism Refreshing my Blog Again Random Rust Impressions Apilar: An Alife System I Was a 1980s Teenage Programmer Part 2: Olivetti M24 I Was a 1980s Teenage Programmer: the Alphatronic SolidJS fits my brain Is premature optimization the root of all evil? Framework Patterns: JavaScript edition Roll Your Own Frameworks Framework Patterns Secret Weblog Highlights Refactoring to Multiple Exit Points mstform: a form library for mobx-state-tree Seven Years: A Very Personal History of the Web
under-engineering, over-engineering, right-engineering
Martijn Faassen · 2007-11-01 · via Secret Weblog

I just ran into a post in a series called "Tools of The Effective Developer". This one is called Make It Work - First!.

The posting contains very good advice. I call the two extremes described "under-engineering" and "over-engineering". It's in part a personality trait as the original posting says, but in part it's also something that changes (hopefully!) as a developer matures.

Inexperienced developers who are still learning the basics of the craft tend to under-engineer. They're happy already when they get something working. They frequently don't even realize there are better ways to do it.

Under-engineering frequently results in buggy, crufty, overcomplicated or over-verbose code that's hard to read and hard to test. It works, but it makes developers miserable, including most likely the developer who originated it.

More experienced developers who are comfortable with their craft frequently end up over-engineering. This problem is compounded if the developer is fairly isolated from having actual users. These developers are comfortable with the details of programming, and they're aware of (at least dogmas of) right and wrong ways of doing things. They therefore have an interest in powerful, flexible code, and a tendency to anticipate future features.

Over-engineering frequently results in code that overanticipates tremendously. It's full of all kinds of interesting features and pluggability points that end up not being needed in the future at all. On the other hand, features that may be essential to the task at hand might not be very well done, as they got lost between all the other ones. Frequently even the (over)anticipated features end up not working properly should you ever need them in the future. This is because there was no real world application to actually exercise them yet when they were being written, causing them to be buggy, or slightly-off.

This stage is probably an essential phase that good developers have to go through. With even more experience these developers can hopefully reach a balance: right-engineering. This is the ability to know when to keep things simple, and to know when not to. These developers really understand the value of good practices like high-feedback iterations and test-driven development. As the original post recommends, typically the right approach is indeed to go for the solution that works first: a simple one. I must note here that 'simple' is a relative concept - a good developer can make things simple that are definitely complicated for others.

I'll also note that sometimes customers affect this balance. Customers might be of a "just make it work" mindset, leaving little time to developers to get things right. This is a well-known phenomenon, much complained about by developers. Less well-known is that in other cases, customers might also overanticipate future needs, complicating the design of a piece of software before they even run it and actually gain more experience with their real world needs. A good developer tries to steer both types of customers to the right place somewhere in the middle.

Right-engineering is difficult. "Make it work first" is indeed one of the most important ingredients to reach success. Right-engineering is more the application of good development strategies than it is pure coding skill. You can't "become" a right-engineer after some period of learning and growth, resulting in you always finding the right balance between over-engineering and under-engineering for the job. What can happen is that a developer will adopt strategies that increase the chances of finding that balance.

A developer should recognize that the right amount of engineering (and what to actually engineer) is highly dependent on how the software is actually going to be used. The best way to find out how software is going to be used is often to actually use it: use your api in automated (doc)tests, get the customer to use prototypes and development versions, and get the customer to put the software in production when it's good enough, instead of when it's optimal. Software development is frequently software evolution. Get feedback and go back and improve your code.