Code duplication, refactor?

The words repetition repeated three times in a notebook. The book is on a wooden table next to a pen and a coffee

Code duplication or DRY (Don’t repeat yourself) is a core principle of software development. The principle itself is solid, duplicated code can and will become a problem. If you have a bug in a piece of code that ends up being duplicated n times you now have n+1 bugs. If you adjusted or tweaked the functionality of duplicated code, same issue, you need to make the same change n more times.

We should try to remove code duplication, which is a given, the question is when?

As with everything, there isn’t one answer, it very much depends on circumstance. For the purposes of this blog post, I’m going to focus on web development. Much of what I mention will apply regardless of the context.

Duplication in views

I’ll start with the easiest one to answer, duplicated code in your views. Views are typically the simplest part of your App. When you have duplicated a section of code more than two or three times, go for it. Create a view component, fragment or whatever your tool supports to remove the duplication.

It is less likely that your view code will fundamentally change, removing the duplication early makes sense. As your experience grows, you’ll end up removing any duplication before it occurs. This makes sense for simple view code that you will most certainly use multiple times.

Controllers

With controllers it depends on what code is duplicated. Is it flow code or is it Business code that should really be somewhere else and shouldn’t live in your controllers.

You should remove duplicated flow code but you shouldn’t make it your priority. Business code deduplication is your priority, it is the code which makes your App do something useful and interesting.

When you are confident you can remove some duplication, go for it, this could be Request handling code, code to prepare the view, whatever lives in your controllers. A good tip, open two controllers’ side by side and look at the code to see the repetition. You will be surprised at how much code you have duplicated and as a consequence, how much you can remove.

Business logic

Duplication in your “Business” logic is a problem. Duplication at this level will eventually hurt you as you will end up with inconsistent behaviour. This is the code which makes your App special, this is the code that you need to work. Problems here undermine your App and annoy your customers.

Regardless, it is still not as simple as “remove the duplication after n cases”. Your business logic is the most complex part of your App, this is the code you are most likely to tweak and adjust.

Before you remove any duplication you need to be certain the code solves your problem. There are going to be bugs and issues with your implementation, especially if it is new code. I would advise waiting a little while. Wait for the inevitable bug fixes or the feature tweaks, make sure the code works first.

We very rarely solve a problem correctly the first time, code inevitably gets rewritten. When you rewrite or refactor the code, remove the duplication then. You will have much more knowledge about the domain, and it won’t be surprising if you solve the problem in a completely different way to the original code.

Don’t worry

When you are beginning your career, don’t worry about code duplication. If a team member or a PR comment asks you to remove the duplication, obviously go for it. As you gain experience, you’ll know when you need to worry about DRY and when you don’t. Your only concern should be gaining experience and solving problems. Don’t worry about writing ‘perfect’ code, no one does.

My Git Workflow

Pipes and nodes to replicate a git workflow of multiple branches merging into each other

I haven’t written about my Git workflow for over a decade. The last time I documented my Git workflow was during a contract. I needed to explain Git to a new employee who was new to development.

My perspective

I’m writing this post based on my experience as a solo developer. Unless I am in a contract, I spend much of my time working solo. There is no reason these workflows won’t work with small or larger teams; your results will vary. With larger teams you don’t get a choice though as the organization decides what is best.

Project Type

The type and state of the project maters. When the project is in the initial stages of development and there hasn’t been a release, everything happens in “main”. A release could be the first alpha release for testers, the initial preview for a client or just the point that feels right. If the project is past its first release, the only question that matters is, public or private repo?

If the project lives in a public repository, all my development happens on a fork. The fork is effectively my feature/dev branch. I will merge back into “main” as often as possible. I will merge when a specific feature is complete, when a bug is fixed or just when it feels right. My work on Budget is an example of this, I have a fork and never commit directly into the “main” repo.

When the project lives in a private repository, all my development happens on feature branches. Where possible these are small feature branches. We all know that sometimes you are going to have the long-lived feature branches, in those instances I will merge main into the long-lived feature branch anytime “main” changes. Budget Pro lives in a private repository so there is no fork, just the main repository.

Feature branches

Whenever possible, yes, small feature branches are the way to go. The only real change in my approach is where the feature branch lives, is it a fork or a branch off “main”.

There are exceptions, there will always be edge cases. Edge cases are different for all of us, you know yours. If your edge cases are rare, it is ok to break the rules occasionally.

If you got to the end of this post and are wondering, well, that seem simple, yes, that is the point. Our work is hard enough, we don’t need to complicate it by adding unnecessary steps to our development processes.

I have avoided talking about continuous integration and continuous delivery in this post, they are topics for a different day. Our first priorities should be making development easy and ensuring “main” is stable.

This post is a continuation of a series in which I talk about me development process. Please check out some of my other posts, my typical project setup and action class usage in my Laravel apps.