Managing Cognitive Load or: How I Learned to Stop Worrying and Love Unit Testing
|tuzgai posted at 2019-02-10T16:35:41Z|
We just hit the one month mark in this course and I think I've identified the biggest issue my classmates are running into - managing cognitive load. When you're making an application of non-trivial size, there's a lot to keep track of! There's the overall architecture, the implementation of each component, the user experience and so on. I think that, much like [how we think we can multitask but can't really](https://hbr.org/2010/12/you-cant-multi-task-so-stop-tr), we think we can hold a whole large program in our heads, but can't in reality.
I've been helping a number of people in my class with their project and the common theme is that they're always jumping around through their code chasing bugs, changing the architecture on the fly and generally feeling chaotic and overwhelmed. This was me not too long ago! But now, I'm generally not too stressed about these projects. Part of this is definitely because I have a head start in programming experience, but I think a big part is that I've given up on holding the whole thing in my head and rely on tools to help me stay organized and focused.
Much like how object oriented programming allows for separation of concerns between modules of your codebase, diagramming and unit testing allow for separation of problem solving and writing code. When you only have to hold one relatively small part of the problem in your head, life is easier and you work faster and hit fewer bugs. This might not work for you, but it's been a huge deal for me - give it a try!
Diagramming Before I write a line of code, I step back and solve the problem on paper or in diagramming software. I sketch out the classes and methods I need and their relationships and if the user interaction is complicated I do a little flowchart to organize my thoughts. None of this is necessarily for anyone but me, but what it lets me do is work out what the overall problem is and the steps to solving it before I get tied down reading the docs for BigDecimal or whatever. Once my diagrams are done, I can move on to implementation and know that if I am ever unsure of how things are supposed to fit together, there's an easy reference nearby. I don't ever think "Ok, what needs to happen next?" because I can just look at my reference. This has saved me a lot of time and energy.
Unit Testing Unit testing works just like diagramming but on a method level. Here's a frequent workflow for writing a method I see in my classmates (and in myself before I learned unit testing two weeks ago ;)).
1. Write a void method signature with no inputs
2. Write part of an inner loop, then go back to add the relevant inputs for the method signature
3. Go back to the code that calls the method to look at what it needs to return, update that.
4. Fiddle with things until Netbeans doesn't have any red lines.
5. Write a tiny console interface to test the method by hand
6. Jump around between the previous steps fixing things until it seems to work. This is a chaotic approach and means that your method is never truly finished - there's always the chance that you hit a big either from the method being incorrectly written or from a mismatch between your understanding of its behavior and it's actual behavior. In contrast, here's a workflow with unit testing.
1. Determine the desired inputs and outputs for the method. You now understand the shape of the problem.
2. Write unit tests to match your understanding of the problem.
3. Write your code.
4. Run unit tests and fix your code until they all come back green.
This approach gives you the opportunity to think deeply and understand the problem at hand before trying to solve it. It also gives you an easy answer as to when you're done. Finally, you can move forward and write code that depends on the method with confidence. It's unlikely (depending on the quality of your tests) that the method will behave in an unexpected way - you have already proven to yourself through your tests that it works correctly.
tl;dr Embracing diagramming and unit tests has been like night and day for the way I write code. Where I once jumped around tackling whatever problem interested me first and chasing bugs as they arose, I now make a plan and execute it with dramatically fewer bugs and delays. As a bonus, I finish the day feeling fresher since I wasn't constantly straining trying to hold the whole project in my head. If you're learning to code and don't do these things, give them a try!Last edited 2019-04-15T14:16:01Z Permalink