Skip to main content

Command Palette

Search for a command to run...

Parallel Change with Example

Changing code implementation without stopping the process

Published
5 min read
Parallel Change with Example

What is Parallel Change?

Parallel change means that when changing a design, you keep the old design as long as possible while gradually adding the new one and then you gradually switching to the new design. Only after that you gradually remove all the old code. The code is never broken. - Holy On Dev

This concept is very common, just remember when you were using a library and some methods or classes suddenly are marked as DEPRECATED but still working in your code, and in the major version is explicitly removed. Well, to do that in a library you must apply this technique.

Expand - Migrate - Contract

To apply this technique you must follow these steps:

Expand

Let's start with some old functionality using this code:

class UserRepository {
    private Map<int, Pair<String, String>> users;

   public void addUser(int id, String name, String lastName) {
      // some code ...
   }

   public Pair<String, String> findUserBy(int id) {
      // some code ...
   }
}

We know the code above is not the better and must be replaced, but some part of our code is using it right now, or if this is a library maybe a user is implementing it in its system, so we can't replace this code, we must prepare the other users for the change.

Expand process is the first step for doing this, with 'expand' we mean that we can create new methods in the class. Doing that we can add the following methods in our class.

class UserRepository {
    private Map<int, Pair<String, String>> users;
    private Map<int, User> recordUsers;

   public void addUser(int id, String name, String lastName) {
      // some code ...
   }

   public Pair<String, String> findUserBy(int id) {
      // some code ...
   }

   // new methods
   public void addUser(User user) {
      // some code ...
   }

  public User findUserBy(int id) {
     // some code ...
  }
}

Now we have two new methods that can substitute the old ones, but we can't remove the first two of them because another system could be using those methods.

Migrate

So here is when migrate makes sense, we must tell everybody that in the future, the old methods gonna be removed, so we marked the two methods before as Deprecated

class UserRepository {
  private Map<int, Pair<String, String>> users;
  private Map<int, User> recordUsers;

  @Deprecated("Please use - void addUser(User user) - instead")
  public void addUser(int id, String name, String lastName) {
      // some code ...
  }

  @Deprecated("Please - User usefindUserBy(int id) - instead")
  public Pair<String, String> findUserBy(int id) {
      // some code ...
  }

  // new methods
  public void addUser(User user) {
      // some code ...
  }

  public User findUserBy(int id) {
     // some code ...
  }
}

By doing this we inform any developer that the library will have a new version soon and must adapt their code to the new version.

Contract

This is the final step and is very easy, assuming we give enough time to migrate the systems that implement our library, we can now delete the deprecated code and release a new version.

Resulting in the following code:

class UserRepository {
  private Map<int, User> users;

  public void addUser(User user) {
      // some code ...
   }

  public User findUserBy(int id) {
     // some code ...
  }
}

More from this blog

Kaito

2 posts

I'm a Software Engineer with 8 years of experience, I started working as a backend developer, across the years I learned many languages and areas, such as Frontend and DevOps.