5 ms·
I have this problem with planning. My planning mostly ends up being sequencing of tasks rather than working how to do them. Software is made out of ideas, and
by cjs_ac 3y ago
I have this problem with planning. My planning mostly ends up being sequencing of tasks rather than working how to do them.
Software is made out of ideas, and code is just a symbolic representation of those ideas. Writing the code is the easy part; working out what ideas to represent is the hard part of programming. If your planning involves working out what ideas to represent, if you do that in greater and greater detail, eventually you stop planning the work and cross over into doing the work.
> File based organization, right from the start you need to start deciding what goes where. Of course I think most of us start with a single file, full of random functions and tests. But at some point this file becomes unbearable, impossible to find what you are looking for. At that point you have to make decisions and start splitting the file at logical points. Deal with what is private and what is not. It may not seem like much, but it's very annoying.
In a project I'm working on at home, I started off with an extremely naive implementation, the single file of functions described above, and when the messiness became unbearable, I started building object-oriented abstractions to make sense of it all. But the structure of those abstractions was discovered while making the mess - if I'd tried to build that at the start, I'd have built the wrong thing.
I'm very fortunate in that in both my day job and my recreational programming, I'm the only person working on that particular codebase at the time. (At work, I develop what are basically plugins for the framework-type-thing that's our main product.) Consequently, I have the freedom to make a mess and clean it up once I've muddled about in the solution space to discover what's going to work best, and so most of the solutions in the blog post are rather unnecessary for me. In the end, two months of work on my home project was thrown away and rewritten, which I could never have got away with at my job, but the project is all the better for it.
- cmiller1 3y ago> But the structure of those abstractions was discovered while making the mess For me at least it's more like bang out the naive implementation mess then "discover" the proper structure of the abstractions in bed that night or in the shower the next morning.
- deergomoo 3y agoThis comment very well captures what I was trying (and failing) to explain to a colleague recently, when talking about why TDD doesn’t fit the way I solve problems. It’s almost like tending to something as it grows, discovering what the solution most wants to be with respect to the problem and the environment (e.g. programming language, server vs browser etc.)
- jdlshore 3y agoTDD was invented by Kent Beck, who also is a big proponent of evolutionary design, which is what y’all are talking about. If the way you use TDD doesn’t fit that way of working, you’re doing it wrong. (The most common mistakes are to write tests up front, rather than in parallel with the production code, or to overuse mocks.)
- deergomoo 3y agoIt's not that simple though. His own article "Canon TDD" [0] still involves writing a test before writing the corresponding code. In my experience, the practicalities of all but the most far-removed integration tests (i.e. when receiving this request, server ultimately returns this response) mean that I would be effectively doubling my workload by having to repeatedly refactor two sets of code as I explore. The TDD steps listed do include refactoring if/when required, but I'm not entirely sure Kent had exploring and comparing half a dozen different approaches in mind for that one. It still seems fundamentally geared towards implementing a solution you've already arrived at. I'm not disputing TDD as an effective strategy—I've seen it work wonders for some of my colleagues and I will still occasionally employ it myself when making additions/changes to well-established bits of code. But, for me personally, I feel I can stay in the flow and get all the same benefits by just doing step 1 ("Write a list of the test scenarios you want to cover"), implementing the code, then actually implementing those tests at the end. [0] https://tidyfirst.substack.com/p/canon-tdd https://tidyfirst.substack.com/p/canon-tdd
- jdlshore 3y agoIf you have to refactor both, something is still wrong. Tests should check behavior, not implementation. Refactoring should change implementation, not behavior. If refactoring requires you to change your tests, something is wrong with the way you test, or with the way you refactor. One common possibility is that you’re writing isolated unit tests (using dependency injection to prevent the code under test from calling its dependencies) rather than sociable unit tests (the code under test runs normally).[1] You do you, though! As long as the code works and is easy to refactor, it’s all good. [1] For more about writing sociable tests, see “Testing Without Mocks: A Pattern Language.” I’m on my phone but it’s easily googleable.
- MarceColl 3y agoYeah, this is very similar to my experience and what I wrote in the article. For me it also feels like the structure is discovered as you explore the program and the problem.
- blarg1 3y ago> structure of those abstractions was discovered while making the mess I often feel like the code I write isn't something I came up with, just something I'm discovering as I go.