Code Rewrite

Three wooden blocks with the words "time" "to" and "update" on them. The blocks are sitting on a white surface against a light background

I’ve discussed in a previous blog post that Budget Pro and Budget are two different Apps. I won’t repeat the rationale here, however regardless of my choice I will still need to rewrite the code for the “budget service“.

What is the budget service?

The budget service receives a collection of “budget items” from the Costs to Expect API. It is responsible for taking these budget item definitions and then creating the users Budget.

Budget items have several parameters controlling whether and how they should appear on the users Budget.

Parameter:Description:
FrequencyHow often does the budget item repeat and how does it repeat?
Start DateWhen is the budget item effective from?
End DateWhen is the budget item effective until?
AdjustmentHas the budget item been adjusted, for example value changed
PaidHas the budget item been marked as paid for the selected period?
DisabledHas the budget item been marked as disabled?
AccountWhich account does the budget item belong to?
TypeWhat is the type of the budget item, income, savings, expense etc.
Parameters that exist on budget items in Budget.

The service iterates through all the defined budget items and allocates them to each period (month) accordingly. From this, the service then calculates the projected balance for each defined account.

Why the code rewrite?

The existing budget service is serviceable. It has warts because features were added after the original design but other than me being unhappy with it, it works well enough and has tests. Me being unhappy with it is not reason enough to rewrite, we would never release anything if we kept refactoring code each time we were unhappy with it.

So, why a full code rewrite?

Well, Budget Pro is significantly more complicated that Budget. In Budget Pro we support multiple period types, many more adjustments, custom display options as well as other changes. Additionally, users can have multiple budgets meaning the service needs to know which budget it is handling as well as the permissions due to sharing features.

The original service wasn’t designed to handle custom display options let alone more advanced parameters. The budget service already feels “wrong” so although I could tack on support for all these features, I would end up with something even more clunky than now and inevitably need to rewrite it anyway.

Struggling?

What is the problem, why the need for a blog post? Well, I’m struggling, and I think I’ve worked out why.

When I created the original budget service I was working from a clean sheet. I had the data the service would use; I had a design to achieve, and I could decide how I got from A to B.

With the new service, I have a lot more baggage; I have the data, I have an updated design for the UI, I know the new features but I also have an example of a service that doesn’t work.

We all code in a specific way and this is the problem. I know what I did before isn’t right; however it does solve the problem. I could go back to basics and design from a clean sheet but that is foolish because of the existing service. As much as the existing service won’t work for Budget Pro, it has been improved over time and works and obviously, some of what it does is correct.

What am I doing?

I’m designing the new service slowly, bit by bit. I’m keeping an eye on the original service but conscious that there are many things that need to change.

The first major change is support for user options. There are multiple sections of the service that need access to user options. For example, the spend ranges for budget items, the number of ‘periods’ to display and colours. I’ve opted to use a Service Provider to register the Budget service and corresponding helper services. This makes it trivial to access the service throughout the App via the Service Container. The next issue is more parameters, specifically the more complex frequencies and more adjustments. In the original service I handled this as I iterated through the data. With a small number of parameters, this is easy but as the number of parameters grow this gets more difficult. I’m going to create data structure that manage each parameter which will hopefully help me keep the core iterating code nice and simple.

Below is a comparison image for the old and new service. As you can see the complexity has increased. However, the new service is much clearer regarding implementation.

Budget Pro and Budget "Budget" services compared. Tree structure of the two services compared, the Budget Pro services contains twice as many files/classes
The “Budget” service in Budget & Budget Pro

Will it work?

Only time can answer that but yes, I suspect everything will be fine. Yes, there will be bug fixes and there will be addons that make my eye hurt but that is working code.

A year after Budget Pro releases I will be in a better position to answer this question. I will have had to tweak things, fix many bugs, some hopefully due to scale and be working on new features. It will be at this point I will be able to say for sure if all the effort was worthwhile.

Long development times

Many vintage clocks on a brick wall

I have several projects I support which had/have long development times. When I say a long development time, I don’t mean bug fixing and support issues. I mean continued development of significant new features or modules.

In this blog post I have two examples, a long-term project for a client which I have been building and adding to for 18 months and the API for Costs to Expect which I have been working on for several years.

One of the significant issues with long-term development projects is ensuring the App design remains consistent. There are many reasons why you might want to change or tweak the design of your App. The original design might not be right as you get further into the project. You think of a better way of doing something or a new tech comes out which could significantly improve things.

The client matters

What you do very much depends on the type of project.

If the project is a personal project, you are free to do what you want. With personal projects we are free to decide when architectural changes make sense and when to do them, it is bliss.

However, if the project is for a client, things get much more difficult, and it depends on your relationship with the client. If you are a contractor, the best you can do is submit a request and explain any benefits.

When you are a freelancer or know you will be supporting the project for a decade or so, it is complicated for a different reason. If it will benefit you to makes the changes, you must decide if it is worth just buckling down and making the changes. There have been instances where I have made changes at my own cost. Many a time I have spent a week or so making some major changes knowing that they are going to make my life easier later.

Some of the time I’ve made these changes for ‘free’, some of the times I’ve been paid. For me, it depends on who benefits. If the only benefit is my time in the future, I tend to make the changes for free. If the changes have the potential to make my life easier and somehow enable additional features in the future, I suggest the changes and try to get paid.

Conclusion

There is no perfect answer. We can’t always predict when we are going to support an App for over a decade. We can also get it wrong. There have been times when I’ve adapted the design and it turns out, it wasn’t for the best.

We are all still learning, it’s one of the things I love about our field. My advice, go for it; if you get it right, you win. If it doesn’t turn out how you’d hoped, chalk it up to experience.