Sometimes I wish these articles would just state: Stop sprinting
Also: document your decisions! If you have to write down and justify your (prudent) technical dept, you maybe catch some stuff before it's written in code. It also makes sure more people are aware of it. Additionally, it sometimes prevents CV driven development, which imho is a big problem in tech. Overall, documentation is a very underused tool.
Finally: teach everyone (especially marketing) that software development is expensive, so everybody thinks twice before wishing for nice to have features done quick.
Steve Jobs' presentation of Snow Leopard should be mandatory viewing for every manager. "No new features" to a standing ovation. Customers actually like stable, responsive, and efficient tools, who would have thought?
EDIT:
> Bringing "microservices" into the room is definitely not helpful
It's a pretty good way to increase technical debt. The microservices themselves might become small enough that it is easy to refactor some at a time, but then you have the actual deployment and communication infrastructure to contend with. And if you get that architecture wrong, oh boy you'll be begging to go back to a monolith in a day.
I remember at a previous job, the monolith was drowning in technical debt. Someone decided the solution was Go microservices. Fast-forward 18 months and 95% of the functionality is still in the monolith, but there are now 25 microservices, and no environment (except production) where you can test everything together.
Additionally to managers watching that presentation, software architects should mandatory have to work as normal developers in every project they designed for a a few months. Best, if it would be around 2 years after they came up with the architecture. If you don't taste what you cook, how can you learn?
I fully agree on your points with microservices.
Stop sprinting is good but also : stop following Google. You are not Google. You do not have the needs of Google. Just stop it.
Pick the simplest tech stack you can find. This gives 100x more time to your developers to work on company solutions and not fighting technical complexity.
_Existing_ customers like these things (and they aren't wrong for liking these things).
New business comes from the potential customers who weren't enticed by the existing feature set, robust or otherwise. You bring them in by adding new features. The retain/new business priority is often heavily weighted in favor of the latter.
Retaining existing customers stuck with a crappy product ain't that hard between sunk cost/lock-in effects and the evergreen insulation of people with purchasing authority from the day-to-day pain inflicted by their purchasing decisions. A couple fancy steak dinners for middle management effectively papers over the cost of driving a department of ops engineers to cirrhosis several times over.
I've been through this slog - sometimes it requires fixing what's there and other times, a rewrite. People hate rewrites, but it really is the best way forward in a lot of cases if done correctly.
This is my experience with many different systems. I’ve found that mentoring and personal development identification techniques for what to learn, and when, can be helpful. Inviting a developer to be part of the decisions made regarding their future may seem obvious, but in practice it’s often not done…
And documentation… I’m known as “Just write it down,” but there is usually significant pushback… from all parties.
This is Fowler (and Uncle Bob's) stock in trade tbh.
Generic good advice that sounds plausible in a sane world.
Without ever acknowledging that we actually don't live in that world.
From [1]:
> In my Ruby code, half of my methods are just one or two lines long. 93% are under 10.
Are there professional engineers out there who reads this tweet and thinks striving for one or two lines methods is a good idea? I really don't understand how does this person have so much fame or so much authority on architectures? What exactly are his accomplishments other than selling books and seminars? Can someone please explain how come Martin Fowler is so revered among developers?
[1] https://twitter.com/martinfowler/status/893100444507144192
Striving for the shortest possible methods (less than 10 lines is good) is a standard in Smalltalk. It's not a bad idea, at least, it's been shown to work over and over again over the last 50 years. Ruby takes a lot of inspiration from Smalltalk, although it lacks the biggest factor that made short methods work so well in Smalltalk: the interactive editing of the code as it runs.
Another example where a subroutine longer than a few lines is frowned upon is Forth. Also in that case, interactive editing is the main motivation, along with the fact that the amount of irrelevant bookkeeping grows linearly (or worse) with the subroutine length (unless you use local variables or the return stack, which are both hacks in Forth).
In any case, "professional engineers" who don't even know Smalltalk... No, I mean, the history and breadth of their field, probably should not be too judgemental about what works where, outside of their immediate expertise.
1-line methods is taking things to an extreme (though you can write a lot of logic into a single line in Ruby, so maybe it's not as crazy as it would be in C...) but I found the discussion in his refactoring book about reorganizing methods and naming things very illuminating.
It's an idea so simple it sounds stupid sometimes to try to explain to people, and yet, I never stop seeing new code that could be improved by something as simple as methods with accurate names.
E.g. I've seen a lot of stuff like:
```
// This does X
[some obtuse nasty inline regex or five-layers-deep nested object call or otherwise crazy individual line of code]
```
That maybe eventually gets detached from that comment line and now there's just some nasty line that nobody on the team understands anymore that can't as-is be easily tested in isolation from a bunch of other stuff.
A perfect opportunity for a one-line method, that can have a descriptive name and can have its own specific tests.
And yeah, again, that's the extreme case, but most codebases have tons of opportunities for 5-10 line methods being extracted with helpful names. If you find yourself writing a comment to describe a block of code, maybe make that comment your method name instead. And sometimes you try it, and realize "wow, it's hard to extract these methods without an insane amount of input params and return values for each bit" and maybe that's an important thing to realize about the code you're looking at anyway. ;)
M. Fowler, Uncle Bob, Kent Beck, GoF authors...
Any book or post by these people is always brought up as a must read. A must read to understand why you should *not follow cargo cults* and see with your own eyes how toxic and damaging these guys are to software engineering culture.
In one hand, I'd say these guys are absolutely revered among computer science students (their main target to sell their books) and developers who have been stuck in the OOP and design pattern rabbit hole for decades without evolving.
In the other hand, the criticism is more present that ever. It's ironic, because the criticism has even lead Uncle Bob to jump the wagon and start to sell Functional Programming in Clojure as a new super *secret formula* and *best practice for real engineers*.
Organizing all those small functions can be a challenge, though. Which is why I don't tend to have functions quite that small. But a lot of 10ish line functions tends to work ok. But then, Erlang doesn't have loops, and I don't like anonymous functions (unless they're so short and simple I don't expect to find them in a stack trace), so that tends to make things short by necessity.
Getting it right the first time is a very hard game to win. It’s best to save some of your energy for the times that really count. It’s always interesting to me when coworkers exclaim that doing the right thing is too hard. Reminds me of myself at age nine trying to get out of chores. More seriously though, “if it hurts stop doing it” is how dumb animals think. Pain is information. Ignoring it is dumb. Almost as dumb as giving up is.
Just last week I was having a hell of a time getting some code to work. Running into a wall. Okay fine, I’ll write more tests. Still struggling. Oh hey, you know what would make this way easier? If I rearranged this code in the manner I thought about this morning but decided to not work on until tomorrow.
If eating the code is difficult, there’s a point of very quickly diminishing returns where adding more logic to the tests is making things worse, and you should think about whether The code is too complicated to test. Maybe you need to remove code, instead of adding it twice.
Clearing debt can be a bit of a fishing expedition, but as long as enough of them have a payoff, it hardly matters if occasionally they come up goose eggs.
I've tried to articulate this (a bit tongue-in-cheek) here: https://www.evalapply.org/posts/software-debt/
In short, I feel a re-scoping in terms of "Software Debt" is warranted. And a re-casting of the risk of this debt in terms of the rocket equation, and opaque financial derivatives of the kind made infamous in 2007/08.
But it only ever happens when the hands-on people get to spend significant time on improving what is happening behind the scenes. That might mean 20% or 50% of their time, not the 2% or 5% that many get.
If the hands-off people calling the shots aren't willing to make that commitment then a heavily indebted organisation's fate is already sealed.
Shameless plug: https://leadership.garden/tips-on-prioritizing-tech-debt/
There’s sometimes bad code that one resolves by redesigning some part of it with eventually some glue code with the old system, documenting it and making a presentation for everyone on how should the new stuff be written, and distribute work for a slow migration of the old systems by the different parties.
I’ve seen also some systems designed to solve problem X while the company or industry moved on to problem Y. Again, act like a virus, infect the system with your brand new solution, glue it or bind somehow with the old system and let it spread.
The only mistake that you can do is to engage all of your resources to undertake a full redesign and rewrite everything from scratch.
And for processes or algorithms that don’t scale, it’s not a debt because you never really made the investment.