Refactoring

Ikey Benzaken
4 min readDec 14, 2020
Source: Lattix.xom

There are two polar ways to build software:

  1. The hackathon method: This method includes throwing code structure and object orientation out the window and replacing it with tightly coupled, functional, everything in the index file, no tests lets just hope it works, code.
  2. The let’s have industry standard code-quality even though four people use this app method: A code editor isn’t to be touched unless a the entire project has been planned out. The app has a mission statement, there are wireframes, an ERD, basic file structure outlined, and many many test cases written.

Even though you might assume that we should strictly use option #2, both of these development strategies have their pros and cons. Option one for example is the method most software engineers use when they work on side projects. It offers very fast prototyping ability, great flexibility (usually written in loosely-typed languages) and can often deliver a solid-looking product. The downside of this approach is codebase maintainability and scalability. When projects aren’t planned in advance, the code is usually written to fit the spec of the app perfectly. No micro services, no abstractions, just a tighly coupled mess that does exactly what you told it to.

Er, uhm, code that does exactly what I told it to sounds pretty good to me? Yeah, it’ll be good, for v1 of your app. But next month when you decide to jump back into it and add a new feature, you’ll learn the hard way that a tightly coupled mess that does exactly what you want, is not at all what you want your code base to look like. It’s configuration is too finely tuned to your original project idea, and most modifications, additions, or deletions, create bugs all over your app. A disaster to work with.

Okay… So method #2 for the win? Not so fast! Method two takes a lot more time than method one. Not to mention, resisting to open a code editor immidiately after an idea pops into your head is a dicipline that requires a certain amount of maturity. It is the opposite of instant gratification. Doing the heavy lifting in the begining to ensure an easy development process in the future.

I like to do a combination of the two methods. I never said they were mutually exclusive! You can pick and choose as you see fit. For small projects, I shamelessly use method one to get them built and done with. But for projects I plan to build out and spend multiple weeks on, I’ll put more forethought into the way I structure my code.

Sometimes, you might think project will be small, go for the hacky way of getting it built, and realize later that you have a way bigger project on your hands. In this scenario, you certainly don’t want to continue down the path of hacking it together. I’ve seen this. I’ve done this. It always ends poorly.

Instead, you might opt for a code refactor.

Code refactors come in all shapes and sizes. Sometimes, it might be faster scrapping an entire project and starting from scratch than it would be to modify it piece by piece. Other, more fortunate times, aren’t as drastic. Subtle code tweaks and design modifications can greatly improve code-quality and scalability.

I recently threw together a crud app using node/express/mongo/handlebars. When I threw it together, I used Handlebars because it’s the view engine I’m most comfortable with, and this app didn’t seem to need a beefier one. However, after most of the app was complete I began to get more excited about its main functionality, and imagined many new features I could add to it.

v1 of my ReadingList repo: https://github.com/IkeyBenz/ReadingListOG

After some light research, I came to the conclusion that I wanted to use NextJs as the view engine for the newer versions of this project. Next has the stateful components that I was looking to utilize, with a hint of sever-side rendering to make passing information between my middlewares and views a breeze.

The plan for refactor was simple:

  1. Convert my handlebars views and partials, into pages and components.
  2. Move all server code into a server/ directory. (For orginizational purposes)
  3. Remove the page routes from my controllers (NextJs has a builtin automatic routing feature)
  4. Split my current server.js file into an express.js and an index.js. (Also for organizational purposes, I wanted to keep the next app initialization code separate from the express app initialization code)

After a few hours tweaking around with it, I was able to replicate the original app’s functionality. Like I said, it didn’t do much from the start. It just allows users to sign up and log in. But now that it’s view engine is more enabling, I’ll be able to add features to this very rapidly thanks to React components.

v2 of my ReadingList repo: https://github.com/IkeyBenz/ReadingList

The commit history of this repo gives a brief overview of the steps I took in order. You can see I started with just the pages and components, then I migrated over the original server files, then debugged a little until it worked.

It took some forethought, planning, and learning of new frameworks, but now I have a refactored codebase that is very ready to scale. I am very confident that the time I spent on this refactor will payoff exponentially as I build upon it in the future.

--

--