Refactoring Adventure: Cleaning Up My Code One Step at a Time🚀

Tasbi Tasbi - Oct 7 - - Dev Community

Hello, world! 🌍 Today, I’m excited to share my epic journey of refactoring a project that had slowly morphed into a wild jungle of duplicated functions, inconsistent error handling, and missing logs. It was like trying to read a map in the dark! 🗺️ But with the magic of refactoring, I turned this project from chaotic into clean and efficient code!

Let’s talk about what I did, how I did it, and the aha! moments (and mini disasters) I encountered along the way. Grab some popcorn 🍿 and let’s dive in!

🚀 Setting the Scene: The Problem

Picture this: I’m working on this open-source project, a tool to generate auto-awesome README files from code snippets. It’s a great tool, but as features grew, so did the complexity of the code. Suddenly, I was looking at functions that were duplicating logic, and error handling was scattered everywhere. Plus, no logging to speak of! 🤯

That’s when I knew it was time for some Refactoring Magic. 🪄✨

🌟 What’s Refactoring, Anyway?

Refactoring is like spring cleaning for your code. It’s when you take existing code and reorganize it – without changing its functionality. The goal is to make the code more readable, maintainable, and modular.

Sounds simple? Well, let’s dive into the journey and see how it works in action.

🎯 Step 1: The Game Plan

First things first – I created a new branch called refactoring so I could clean up my code without accidentally breaking everything on my main branch. That way, my project could keep running smoothly while I got into the weeds.

\bash
git checkout -b refactoring
\
\

With my refactoring branch ready, it was time to tidy things up – piece by piece.

Step 2: Extract Functions and Modularize

The first issue I tackled was code duplication. File handling logic, API request logic, and other tasks were all over the place. If I had to make a change, I'd have to do it in several places – yikes!

Here’s what I did:

  • Extracted reusable functions for handling file input/output and making API requests.
  • Created a ConfigManager class to centralize configuration handling.
  • Modularized the output handling into a new OutputManager class.

This cleaned up my code quite a bit. Now, whenever I need to adjust file handling or API logic, I can do it in one place instead of hunting down multiple lines of repeated code like some lost treasure. 🏴‍☠️


🌟 Refactor #2: Configurations Under Control

Issue: Configuration settings were handled inconsistently throughout the code. I was manually setting API keys, models, and paths in multiple places. If I had to switch the model or tweak an API key—good luck finding all the places!

Solution: Time to centralize! I introduced a ConfigManager class to bring everything under one roof. It handled:

  • API keys.
  • Model selections.
  • Output directory settings.

Now, all config-related changes are managed in one place, making the code easier to read and modify. Plus, no more scrambling to find where I set the API key last! 🔍


🌟 Refactor #3: Output Handling on Fleek

Issue: Saving files and output handling was, well, a mess. Markdown files, JSON files… they were being saved all over the place. There was no proper system, and if I needed to update how files were saved, I was staring down at scattered logic across the project.

Solution: Enter the OutputManager! This new class took over the responsibility of saving all output, whether it was a README file or a JSON file. Modularized output means cleaner, more maintainable code and fewer chances of accidentally overwriting files or saving them in the wrong location. 📂


🌟 Refactor #4: Logging the Journey

Issue: Logs? What logs? My program was silently running without any feedback. If something went wrong, I’d be scratching my head wondering what happened. Debugging? Pfft, forget about it. 🧠

Solution: I added logging! I made sure the program would let me know what was happening at every step:

  • Info logs to confirm when things were running smoothly.
  • Error logs to tell me when something went wrong (and, more importantly, where it went wrong).

Now, I get to watch my program work in real-time and catch errors before they turn into nightmares. Logging is my new best friend! 📜✨


🤯 Interactive Rebase: Squashing the Chaos

After all that refactoring, my Git history was looking a bit… cluttered. Four separate commits for different refactors. I decided to clean up my Git history using an interactive rebase.

  • What is this magic? It allows you to combine (or “squash”) multiple commits into one!

Here’s how it went:

  1. I ran git rebase -i main\ and got to pick and squash the commits into one.
  2. I had the chance to rewrite the commit message to reflect everything I’d done in one clean summary.
  3. It felt like tidying up my workspace after a project. It was so satisfying!

Once the rebase was done, my Git history was clean, and my commit message looked professional. 👌


🐞 Bugs and Breakdowns Along the Way

Now, I wish I could say everything went perfectly, but this is coding—we know that’s not the case! 😅

  • Mini disasters? Oh, definitely! There was a moment when I accidentally added files to the commit that shouldn’t have been there. That’s when I met my new friend, git reset\, to undo that mess.
  • Did I break the program? Of course, a few times! When I refactored the output manager, I momentarily forgot to handle streaming properly, and the JSON files weren’t saving. Oops! But after a few logs (thanks to refactor #4), I was back on track.

In the end, those bumps along the way just made the final result all the more satisfying.


🎉 Final Thoughts: A Clean Codebase is a Happy Codebase!

Refactoring is like spring cleaning for your code. It can be frustrating and slow-going at first, but once you see the results, you’ll never go back. With all the changes I made—modularizing code, centralizing configurations, cleaning up output handling, and adding logging—I feel like I’ve turned this project into a well-oiled machine. 🛠️✨

And let’s not forget the Git rebase. There’s something deeply satisfying about squashing all those commits and seeing a clean, tidy history. It’s like looking at a neatly organized closet after decluttering. 👕

If you’re working on a project and things feel out of control, don’t be afraid to refactor. You’ll thank yourself later. And remember, a clean codebase isn’t just about keeping things pretty—it’s about making sure your future self doesn’t hate your past self. 😉

Happy coding! 🧑‍💻🎉


P.S. You can check out the refactor commit here: My Refactor Commit

. . . . . . . . . . . . . .