Parallel Change with Example
Changing code implementation without stopping the process

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 ...
}
}
