archive.org mirror: https://web.archive.org/web/20210721043921/https://terem.tec...
archive.org mirror: https://web.archive.org/web/20210721043921/https://terem.tec...
- Test features, not units (the time spent vs time saved is meh). So when something breaks, you can take it from there. Start digging.
- Build features
- Fix bugs by first writing a test, and then getting green
- Never go over-fancy with inheritance and whatnot. Readable longer functions are preferred over smaller once that break up the logic. Keep the poor soul in mind that has to go through your code in 3 years time. That could be you yourself ;-)
- Comment the "why"
That's it really. For web applications. Seems to work perfectly well for a code base that's over 10 years old and has seen many a developer come and go. Yes there's a bunch of legacy, but not a single part of it that's hard to reverse engineer with some effort.
This might be my ops side speaking, but often undesired behavior aren't outright bugs (a value not being set is expected, but that empty value led to an empty template which led to the frontend framework not reading an event might not be), the same class of issues can be monitored for. This is a combination of logging and monitoring, of both events (where the application checks for unexpected results) and of state (where something external to the application reacts to for example things like active users without login sessions).
Might I add that testing for security should be a priority. Some agile shops move so fast because they aren’t worried about small bugs. All security issues are bugs and often they are ones that aren’t along normal feature usage.
Isn't that why people move company every few years :D
Complaining about crap legacy code is easier when it hasn't got your name at the top
So much this.
Personally, I've grown to prefer object composition for bucketing and sharing reusable functionality across classes over the years. Testing with mocks becomes far easier, and it really seems to simplify the mental model.
Nowadays, I only use inheritance when working with generics and generalizable interfaces.