5 ms·
Writing the overall design in plain English before writing the implementation. Not super detailed, but the main data structures and invariants and mechanisms th
by antirez 6y ago
Writing the overall design in plain English before writing the implementation. Not super detailed, but the main data structures and invariants and mechanisms that will make the implementation working. Then start the implementation refining such document as I discover new things.
- cursork 6y agoAbsolutely this. When facing a tough problem it’s a great tactic to write out what you’re trying to solve and how you plan to solve it in prose-style English. I’ve done it often without ever sharing my writings with anyone at all, and always felt that the code turned out relatively good as a result. I’d also add that a very prototype that you throw away also helps line up your thoughts. The key is having something reasonably concrete in front of you that forces you to think of the invariants, compromises, etc in the system. Before making all those decisions concrete by writing loads of code
- throw1234651234 6y agoThis is the most useful post so far. I take it a step further and make a diagram in draw.io to understand exactly the data that is coming in and out. This is especially important for working with legacy code where you might get random crap like a name instead of an id and that could throw off your design.
- mxschumacher 6y agohere is another useful tool to draw graphs/flowcharts: https://whimsical.com/ https://whimsical.com/
- andreygrehov 6y agoI'm trying to be better at this. Any examples/recommendations you could share?
- ianamartin 6y agoNot sure if this is what antirez had in mind, but when I'm working on stuff, I whiteboard (if I'm at home--and who isn't these days) or write in a notebook. First thing I figure out is how I want to interact with a thing. Whether that's a program or a class or a function. How do I want to call it? What parameters do I want to pass? What do I want it to return? How do I want to use what it returns? So, basically, write the interface first. If I'm building something with multiple parts rather than a single class or function, I'll map out how these things all work together. A loose graph of interactions. Invoke A and have it return X; invoke B and pass X to it and it returns Y; etc. Then I'll consider failure modes and think about what should happen if something doesn't work out quite right. Is it possible to route failures to a centralized cluster of error handlers so I don't have to implement error handling at every level? Finally, I'll think about whether I can map behaviors to defined data structures instead of controlling flow with if/else patterns. Once I have all that written down or mapped out, then I'll start implementing from the outside in. Stub the object, methods and return dummy data structures that fit until I have a complete system that's interacting the way I want. Then I go in and implement the actual functionality I need. The last part--implementing functionality--often implies modifications to my initial thought process. But it's easier to understand what those changes affect if you've already mapped your design. So you might think B can produce Y with I parameter. Maybe it turns out you can't. So now you need to add a new param. Where is that going to come from? Well, you don't have to invent that out of nowhere because you've already mapped out what is happening. You know that you need to either add another node to the call graph or change the return value somewhere else. By the end of the process, you have a working program, and you've also done a lot of your documentation work as well. Again, I have no idea if this is what anyone else is talking about here. But this is how I personally work. It annoys the hell out of some people. But it works for me and helps me create sane software with interfaces people can remember over time.
- mfsch 6y agoThe way I do it is that I whenever I start working on some functionality and it’s not immediately obvious how to implement it, I open a text file and write down my thoughts as something between stream of consciousness and design document, usually formatted as a multi-level bullet-point list. I start with what I am trying to achieve and list the different design approaches I can think of, adding advantages and disadvantages of each one as they come to mind. By the time I’ve written down all my thoughts on a design decision, it is often clear to me which approach I favor. This can be repeated for more and more detailed aspects of the implementation (e.g. “which function should this be added to” or “what to name this function/struct/variable”) until I feel like I can come up with the remaining details as I’m writing the code. If I get stuck somewhere later on, I can always go back and add more details in the text document. For larger or more important features, this list can be cleaned up and become documentation or perhaps a comment somewhere, but I often find that the writing is a useful tool to get unstuck and to clarify my thoughts even if I end up never reading it again.
- desc 6y agoThis, most of all. Substitute native language if not English; the important thing is that the project be defined and developed in both a human language and a computer language, so that mismatches can be identified and resolved. * Start by describing what you are trying to do. * Specifically. * Not 'build a web business to enable users to achieve their potential', not 'create another library for X but simpler' but *specifically what the software will do* and, most importantly, the priorities of scope increase (it'll happen anyway; just get the priorities and their order down in text ASAP). * Put it in a readme.txt or something. * For any given subsystem of the code (meaning: any section which can sort-of stand on its own) write another such file, in more detail. * Let these files guide your tests too. * Keep them up to date. If priorities change, *start* by updating the readmes. The code isn't immutable; nor is the plan. But the plan comes first. * When unsure how a new subsystem or feature is going to work, write out your ideas and thought processes in text. Don't start coding at all for a day or two after you sketch out the basics. *Append* to this file instead of replacing large parts. [edit] Wasn't intended to quote that part (sorry to mobile users) but I can never remember how to get bulleted lists on this site...
- sunsetMurk 6y agoHave any samples/examples you can share?
- antirez 6y agoThings like that https://gist.github.com/antirez/ae068f95c0d084891305 https://gist.github.com/antirez/ae068f95c0d084891305. Usually more detailed with data structures, but this one was a very conceptual thing.
- Xelbair 6y agoI found that combining such approach with writing down basic interfaces works really well - after i have a rough written idea i iterate over interface design with full descriptive comments of both the interface, and the methods.
- amirathi 6y agoThis is coming from creator of Redis so we better listen :) Thank you for your work Salvatore!
- discreteevent 6y agoLeslie Lamport thinks the same: https://dl.acm.org/doi/fullHtml/10.1145/2736348 https://dl.acm.org/doi/fullHtml/10.1145/2736348 Even a rough sketch is good enough a lot of the time: https://m.youtube.com/watch?v=-4Yp3j_jk8Q https://m.youtube.com/watch?v=-4Yp3j_jk8Q
- miku86 6y agoExactly this one. I don't get why the top comments are all about some technical tooling, as if the major part of a developer job would be typing.