TDD has costs. It's expensive and only works on certain types of systems. It also makes exploration of the problem domain extremely costly and makes refactoring a nightmare. I dislike TDD full stop but there are some domains where it's unambiguously a bad idea.
It implies:
- Behaviour can and should be compartmentalised
- Certain types of efficiency are ignorable
- Data structures are better off being relatively simple
- Behaviour is able to be understood before the system emerges
- The system doesn't fundamentally need a lot of mutable state
- Dispersing functionality across small, atomic functions (that obscure sequential flow and state mutation) is good for the code
- It is easy to extract the functionality of this system into pure functions
- A high-level veiw of the system is unnecessary (!)
- In this system, most bugs will come from small units, not interactions between units
- Behaviour of units is likely to be relatively unchanging
- Refactoring primarily happens between interfaces, not to them
- Test rigging is cheap and easy at every level of abstraction, or at least that it's better to contort your system into a structure where that's true
IMO if designing for future use cases is hard, you probably don't understand the problem well enough to be designing for future use cases. Any design you make will be wrong. Write what works and budget in the rewrite.
And if you're a beginner, what you think is high-quality code is probably just wrong. You don't have the experience to differentiate. Over-abstracted code that is extremely visually clean at each of its 8 levels of indirection and is so perfectly cohesive that any modification would destroy the entire artwork looks great to most beginners.
Mirror neuron mythos is ridiculous. They're just normal neurons, they just happen to fire in response to externally observed behaviour as well as personal behaviour.
They aren't magic, they can't actually mirror what's going on in another person's head or give you a high-resolution idea of how their brain works. They aren't even that good at mimicry unless you already have a pretty high-resolution understanding of what you're trying to improve. You can't learn to juggle by watching people juggle. You can't learn to play piano by watching people play piano. You might be able to improve those skills if you already have them and watch someone who's better, but it's limited and whether that's even osmotic mirror neuron activity is controversial.
It implies:
- Behaviour can and should be compartmentalised
- Certain types of efficiency are ignorable
- Data structures are better off being relatively simple
- Behaviour is able to be understood before the system emerges
- The system doesn't fundamentally need a lot of mutable state
- Dispersing functionality across small, atomic functions (that obscure sequential flow and state mutation) is good for the code
- It is easy to extract the functionality of this system into pure functions
- A high-level veiw of the system is unnecessary (!)
- In this system, most bugs will come from small units, not interactions between units
- Behaviour of units is likely to be relatively unchanging
- Refactoring primarily happens between interfaces, not to them
- Test rigging is cheap and easy at every level of abstraction, or at least that it's better to contort your system into a structure where that's true
None of these things are a given.