How to refactor a critical screen of your app in a safe way

Miguel Ibáñez
Mercadona Tech
Published in
5 min readMar 10, 2020

This post is a description of the process that we followed in Mercadona Tech to refactor our Order Detail screen, one of the most critical screens within our Android and iOS public apps.

Why is it a critical screen?

The goal of this screen is to show all the info regarding a customer’s order, as well as its different states, from confirmed to delivered. What is most important is that they can edit the order if it is still not prepared, making this one of the most used features of our app.

Step 1: Seeing the big picture

Once we receive the awesome new design for our screen, we take some time to analyze, discuss, and try to find out the best strategy to complete the task. Talk with your team as much as possible, probably someone faced a similar task in the past and can give you some valuable tips, be open to hear other’s opinions. Sharing knowledge is a must for the success of our team.

Before and after
Each red square is translated into one PR

Step 2: Divide and rule

After analyzing the whole task, it’s time to split it into smaller sub-tasks. To split them we have to take into account the following points:

  • Think about your teammates → PRs should be short enough to improve code review quality and speed.
  • Add value → Each PR should be big enough to add a complete piece of functionality.
  • Definition of done → Each piece of functionality should be properly tested manually and have its tests in code before merging. It’s our responsibility as engineers to ensure that the code we write works as expected.

Step 3: Don’t throw away the current screen

At first sight, you can think about just replacing the current screen’s code with the new one. But if you remember the title of this article, “In a safe way”, we want to refactor our screen without affecting the user. Since our current one can be our best lifeguard, maintaining both versions will help us to be safe and iterative, do continuously delivery, submit small PR’s etc etc.

As humans, we can make mistakes, even if we have a really good test suite and do proper manual testing, it’s normal to introduce any bug during our refactor, and as we mentioned before, the Order Detail screen is a critical screen in our apps, we want our users to be able to modify their order delivery address and time, modify the products included…

To avoid this situation we decided to maintain the old screen code and add new files for the new code. To distinguish between old files, class names, resources… and the new ones we added the New suffix where needed.

This allows us to control which screen will be shown remotely via a phased feature flag and, in case we detect an issue, we can swap them minimizing the impact towards our users while we fix it. We use Firebase remote config to manage this feature flag.

This approach has also a couple of cons:

  • The refactor will be slower as we have to re-write and duplicate code instead of just changing the current code, but sadly most of the times safe and fast don’t fit in the same equation.
  • We’ll have duplicated code and files for a few weeks until we consider that is safe to delete the old code. Fortunately modern IDEs will help a lot doing this.

To know more about how we release our apps in Mercadona Tech, watch Antonio Escudero’s talk about How to Continuously Update your Native App and not Die Trying

Step 4: Reuse what can be reused

Duplicating the screen files and code doesn’t mean that you have to write all the code and create new layout files again from the beginning. Reuse as much code as you can, as this code is currently working and tested.

The test suite for the new screen should be the same as the old screen. We are not changing the behavior with the refactor, we are just updating the UI. So we can use our current suite of tests, which are defining the behavior of the code, as a scaffold to build the new screen piece by piece, adding again safety to the process.

Step 5: Track your brand new screen

Your new beautiful screen is finished, it was launched in the last release of your app, job is done and you’re happy…well no. Now it’s time to track the new screen. To do this we use Firebase Analytics and Crashlytics.

  • Check Crashlytics for any issue that may appear related with your new screen.
  • Use Analytics to check the number of users visiting you new/old screen version. This number will depend on how you did configure your feature flags.

Use the combination of these two metrics to decide when you can go ahead to the final step.

Final Step: Remove your old screen code

Once you consider that is safe to remove you old code just burn it…and don’t forget to remove all the new suffixes in the new code!

Well done, the refactor is just finished!

Conclusions

Despite being a critical refactor and thanks to following the flow described in this article, as well as others already implemented in the team which are described in the linked talk, after one month in production we had no issues related with the new screen and we keep on maintaining a crash free session rate over 99.90% 💪. So we can say that we safely refactored our Order Detail screen 🎉 🎉

If you like the way we work in Mercadona Tech, and you want to join us in this amazing journey, check out our open positions, we want you!

--

--