Recently I was given the task to fix a bug in a very complex component with some mind bending recursiveness going on. It took me days to wrap my head around everything but I eventually got through it.
These 7 powerful principles helped me to tackle the problem:
1. Think first, then code
My first tip is to step back and think about the problem first. Maybe draw a little sketch, create a diagram, write down your thoughts or talk to somebody else about it if you can.
Separate the coding environment from your thinking environment, meaning, close your editor and work on a piece of paper, whiteboard, or inside a diagram tool.
Only when you fully understood the problem and have a clear strategy to work on it, it's time to dive into the code.
2. Break down the problem
Complexity is really just a bunch of simple problems chained together. Try to break down your task into smaller chunks that are more manageable.
This is the hard part, because it requires some training to understand how bigger problems are made up. Only thing that really helps here is to have seen a lot of simpler problems before and try to recognize patterns.
3. Fix your data first
Lot's of problems arise because the underlying data is structured in a way that causes unnecessary problems along the way. Of course it's not always possible to change the underlying dataset, but maybe you can normalize it to avoid running into edge cases.
Sometimes filling optional parameters with empty values is all that it takes to reduce upcoming headaches. Or you just have to add a single additional parameter to simplify the codebase.
So if it is a possibility in your project, take the time to think outside the function that you work on, and also try to consider tweaking your data to avoid edge cases.
4. Start with a MVS
Your MVS is the MVP for your problem. A "minimum viable solution". I just came up with that term, so don't start googling now.
Your MVS should just demonstrate that your fix or feature works. Think of it like a mini version of an MVP. Intentionally skip edge cases and only focus on the meat of the problem.
For example, in the coding problem that I faced, the recursive functions called a chain of 10 other functions. To begin with, I started commenting out all of that and only focused on the core functionality. From there I slowly added more logic as I proceeded.
5. Ignore everything you know about clean code
Ditch everything that you learned about how to write clean code. Move fast and break things. Did you repeat some logic along the way three times? Good. Is your function starting to approach 300 lines? It's fine!
You can clean up all of that later. Focus on the essence of the problem. The 80% that matter instead of procrastinating by thinking about how to group your functions in a logical way or debating about how to call your variable names.
6. Abstraction is your Enemy
Your problem is complex enough. Don't start to introduce additional complexity through abstract classes or factory design patterns... Sure sometimes that stuff is beneficial, but the priority here is simplicity first. Don't abstract anything unless you really have to!
7. Don't forget to clean up
While some of these principles might help you to quickly find a solution to your problem they might leave you with a little mess. That's why it's important to clean up afterwards. Make sure to think about your coworkers and ideally leave the code in a way that others won't face the struggles that you had. Thoroughly test everything and leave some notes of your findings.
Summary
Working on a complex problem can be frustrating but at the same time very rewarding if you manage to power through it. Hope you found these tips helpful and I'm looking forward to hearing your tips on how to deal with complex coding problems?
Side note: If you need professional support on a Vue/ Nuxt project reach out to me on https://nuxt.wimadev.de
Top comments (25)
MVS = minimum viable solution -> I love it! 👻
MVP = Minimum Viable Product (2001) which was used to curb gold plating.
from The power of progressive enhancement
Perfect illustration! keep the vehicle functional early on :-)
Let's spread this new concept :-)
haha, I was just talking about building something crappy that works really fast. Not sure if that's a new concept 😅
Even if it is not a new concept, it really worth to remind it :-)
True.
Then let's spread the word 🙏🏻🤠
Me too, I found the tips simply incredible and real, I have "experience" in legacy code and basically everything he said I apply and it's enlightening to see this in such a well-written post, it opens your mind, thank you very much 🦤.
Happy to hear that! 😊
Unpopular opinion: Nobody ever does point 7 after breaking things.
If one of my peers hands me code saying they'll clean up later, it'll be an instant refusal to review whatever mess they developed
Then again, the MVS part is rather brilliant. Gonna keep that in mind for sure.
Clean up is a MUST.
To make it clear: I do not recommend to hand over half baked solutions to anyone.
But rather quickly hack something together that works first, and make it pretty afterwards and only then hand in the PR.
Really really good article. We get paid to solve problems, not write code. The client doesn't care if something is in a factory, they care that their feature is developed and their business is making money and moving forward. But as always, before that code gets into main, try to clean it up!
Nice advises, thank you
🙌🏻
Addition to 7: don't get emotionally attached to your prototypes! Prototypes are for validating, you should be happy if you can throw them away after you validate your hypothesis :)
Good point! 🤝
Thank you very much for the insight
You are very welcome! :-)
Great advice, thanks🙏🙏
❤️
Nice
Glad you like it <3
Long comment 🥴
My thoughts
My approach to tackling larger problems is to first test some of my assumptions using code that is not overly complex, but rather clean. This is what I am accustomed to, and it is difficult to abandon years of clean code practices.
Once I have successfully tested several hypotheses, I begin combining them together. This is when things become challenging because I need to maintain a codebase while still experimenting with different solutions. This often leads to multiple re-writings of the code.
This is where clean code can both help and hurt. While rewriting code takes extra time, I believe it is worth it because it provides more control over the code and predictability. This is crucial because you need to be able to prove that ideas are achievable or valuable, rather than having to convince others.
The purpose of creating a Minimum Viable Solution (MVS) or Minimum Viable Concept (MVC) is to present it and determine if it meets the objectives. If it does, you may not immediately start working on this idea yourself, or it may not be your responsibility at all. That's why "clean code" practices are so important, they are not only for you.
We should find that right balance between code that is not too messy and code that is not too clean, which could be difficult.
Abstractions
The last point that I don't like about this article is abstractions. I mean, maybe this is your experience that you're sharing, but personally, I like to create abstractions when trying something. This helps me explore many different solutions to see how they would work. Why limit yourself in conceptions when the goal is actually to find a solution?
I apologize in advance, maybe it is my pursuit of perfection, always striving to find the best solution, but this is how I grow. I am tired of spreading bad code all over the place and just to validate MVS or MVC.
I can't agree more. I lived through all of this. Thanks for sharing.