|
Not OP, but I find TDD ridiculous as well. Thinking strategically is understanding the trade-offs of your code, and coming up with good abstractions, that take these chosen trade-offs into account. You want to express the business problem in a language that is close to the domain, and then write a translation (and sometimes the translator) to the language closer to the metal. Coming up with the correct language how to express it (the language can be as simple as recognizing that your problem is a general one on which you can apply a known algorithm) is precisely the strategic thinking. Applied top-down, it also means exhaustively understanding states of the application and major data structures (for example, database schema) and designing the functions around that. It can also be applied bottom-up, by building reusable tools and building blocks, which are independent on the global state, and then connecting them as simply as possible (this is also sometimes called hexagonal design). Both top-down and bottom-up have pros and cons. I am much in favor (instead of too much unit testing or TDD) of building better abstractions that make humans less prone to errors (these can even be DSLs), building assertions into your code that warn you something is amiss (and can also be used in property tests), and always testing against something (i.e. the test code doesn't use the same assumptions as the program it is supposed to test, which is a big issue I have with unit testing). The best parts of the code are the ones that you don't have to test - if the compiler (or your abstraction) can guarantee you an assumption about your code, then you don't need to worry about it being wrong in the first place. And in particular, the problem with "x+y in C++ can launch nuclear missiles" is not syntax, it is a weak type system (ideally you would use something like Haskell that controls the side effects). Again, using checks in a stronger language is a strategic, not a tactical decision. |