How to survive with internal library

Or how to live for several specific users

This is the story of how I started to work on a small library that was used within the company for implementing the same feature in different domains. Let’s name it Address Book. Address Book was meant to be a separate module, since the simplicity of its definition and easiness of its isolation. But more than that, since we had different products placed in different repositories, we needed to place Address Book in the third repo to be able to use it in both domains.

The story of how I merged to approaches

So what I had in the beginning:

  1. A module that represented a telephone book for the third domain (placed in its codebase), which implemented another set of features and also had its own wrapper to work with 3rd party service.
  • The Telephone book module was not fully isolated from the project, so I needed to isolate it first
  • This module also contained the work with some handy utils we had only on this project. So I had to decide what to do with that. To not duplicate everything I spoke with another team and we agreed to create a library for handy utils, so I placed everything there. Which also took some time, because when you know that your code will be used not only by your team but possibly everybody in the company, you start to filter out more.
  • After that clean up I needed to move the isolated module into the library.
  • And finally, I needed to integrate that library with the 3rd domain, instead of the old module, which I moved previously.

Just a beginning

The point is that it took so long, but still it was just the first big step to merge everything. And to be honest the second step had a distance of eternity. The step of refactoring and merging cores together, some internal approaches together. Step on which nobody had time because everybody needed new features.

Refactoring is a must… but painful

The main pain in the refactoring of the library, that everything which is public is the potential component used by the client of the library. Thus, if you want to change it, you must make it deprecated and put a new approach near. Thankfully in my case, I have no tonnes of the users, I have only 3 and all of them are domains of the main big super-app project. Which means, I can clone all 3 repositories and check, what functionality they used. I know that seems a bit of a hack, but we should utilize everything we have and provide the solutions attached to our situation.

  • I created a special annotation that indicated the version from which some method appeared, which helps me to remember, in what time what was added.
  • What was not used outside the module or by the clients of the library, I marked as internal.

When different users use different approaches

Actually, the library itself consists of two parts:

  1. The activities/fragments that are written in the library to work with this core and provide some UI of working with address and phone contacts, so the user of the library, will just run the activity and the rest will be done inside

Concentration is a key

Another problem of working with such libraries (which have different approaches, a lot of stale code, and several clients) is the concentration. I know that it may sound stupid, but when you work on the common feature in your project, in most cases architecture is defined, the utility methods are here, colleagues are here to help if something is not familiar.

Why do you need backward compatibility?

Since the library is used by 3 clients, you may ask “Why do you need backward compatibility”, just release a new version whatever you like, put changelogs and announce that to the other teams. Whenever they want, they will migrate to the new version.

@Deprecated(
message = "Use CompleteCallback instead of this. ResultCallback will be removed",
replaceWith = ReplaceWith("CompleteCallback", "com.careem.chat.core.models.CompleteCallback")
)
interface ResultCallback : CompleteCallback

Afterwords

Working not inside the isolated project, but the project, which is used by other engineers, can add new experience and can be really challenging, but at the same time it's really interesting.

Love being creative to solve some problems with an simple and elegant ways