I'll give you the cheat sheet: - Good design is a single idea pervaded throughout. - More generally, your goal should be to minimize surprise. - If your system allows it, people will do it. - Everyone will not just. If your solution starts with "if everyone will just..." then you don't have a solution. - Isolate the parts of your system that transform data from the ones that use it. Data models outlive code. - Coupli…
I don't agree with all of these, but I'll add a couple of my own: - The ultimate goal of software is to solve the immediate problem at hand. The secondary goal of software is to solve likely future problems with as little work as possible. Any bad design which is better on those goals than a good design is actually a good design. - Make your interfaces easy to use correctly and hard to misuse. Think of how people unf…
I find this principle to hold only superficially, and once subjected to scrutiny it breaks down.
There is a reason why Don't Repeat Yourself (DRY) was superceded by Write Everything Twice (WET). There were far too many junior devs swearing nonsense such as how a DRY abstract class that is inherited by two concrete classes is simpler than two classes or even functions that do mostly the same thing. These junior devs rolled out convoluted abstraction layers in name of DRY that would make enterprise code blush. Moreover, these simplistic yet fundamentalist DRY tricks introduced coupling between components that are similar at a superficial level but semantically held no relationship.
Instead of rolling out premature abstractions, code must allow duplications. Copying a class poses a far lower risk than dumping a sea of inheritance with a bunch of abstract classes and interfaces and generics. The job of a software architect is to save developers from themselves, and minimizing code is such a way.