8

In the past, I used the standard way of adding @Deprecated annotations to API methods which will be removed in a later version.

Now I am preparing a major version for a library, with many API parts removed and renamed.

To make the transition easier for existing users, maybe it could be helpful if the new library version can be used side-by-side with the old version.

Advantages

  • dynamic switching between version can be implemented
  • applications can fall back to the previous version if bugs are found in the new version (useful in beta phase)

To do this, I could simply move the new library version to a new package from com.mycompany.library to com.mycompany.library.v2

Is this a common practice or are there other recommendations for such side-by-side usage of Java libraries?


Background:

the library is a simple document converter. So besides a convert(in, out) mehtod, it has many configuration properties and some event handlers. If I provide side-by-side usage, consumers could dynamically instantiate and configure them:

if (useVersion2) {
  com.mycompany.library.v2.Converter c = new com.mycompany.library.v2.Converter();
  // configure and run
  c.setOption(...);
  c.convert(in, out); 
} else {
  com.mycompany.library.Converter c = new com.mycompany.library.Converter();
  // configure and run
  c.setOption(...);
  c.convert(in, out);
}

(question moved from https://stackoverflow.com/questions/37192945/)

6
  • 1
    What will you do at version 5? 5 'if/else if', a 'switch' ?... Think in a long term and think as you would not be there to get rid of the code. Would you like to see hilarius if/else every where? – Laiv May 12 '16 at 18:04
  • @Laiv code example illustrates how existing v1 users could - for a short time period - include both versions in the same application, until they are done with their migration to v2 (see question title) – mjn May 12 '16 at 18:12
  • for a short time period. We both do know what It's temporarl means in software engineery. Doesn't we? ;-) – Laiv May 12 '16 at 18:39
  • 1
    I can't speak for others, but I'd be hard-pressed to find any circumstance when I'd want to use multiple versions of the same Java API at the same time. – Eric Stein May 12 '16 at 19:29
  • 2
    You could add the @Deprecated annotation to your code. Then, on the release, when people update, they'll see that code is deprecated and they should change. After that, remove the code all together. – Zymus May 12 '16 at 20:55
3

This approach is rather common. It allows a smooth transition to a new API, and a safe evolution towards new implementations.

Of course, the if/then approach, as highlighted by Laiv in his answer, has some drawbacks. It's tedious. It's easy to forget or to mixup things. Ideally, the use of wrappers, factories or adapters could provide some nicer alternatives. But often, the simpler is the better.

Martin Fowler and Pete Hogdson have recently theorized about this topic in an excellent article in which they describe what they call "feature toggle patterns". It might interest you as different implementation strategies - such as the use of a "toggle router" - and usage scenarios are described in full details.

Note: personally I'm not found of feature toggles. Coming from C++ world I prefer the easy and robust alternative using namespace aliases and using clauses to choose at compile time the version to use. But it's language specific, and furthermore it doesn't allow for dynamic configuration as the feature toggles. So as said, sometimes, the simpler is the better ;-)

2

Retrofit library is a great example for this. It's not been that long since they introduced a stable version 2 which is really good even if it did bring some breakages.

Some of the notable things that they did were:

  1. The new API has a lot of value and addresses much of the shortcomings of the older version. This means that your new API must be very good. Not only in terms of how it works, but also make it look nice and easy, if that was ever a problem.

  2. Beta version for the new API was released letting the users learn of the changes early on and even provide good feedback.

  3. Transition wasn't that painful either. They introduced version number in the package name itself, meaning some changes only required modification of the import statements. Yes, some classes were removed and some introduced, but it didn't feel too drastic. This also does depend on how user has organized their codebase which is partly out of the scope of the API developer.

Additionally, migration guides are preferred. Retrofit, being a popular library, many articles regarding this are available online.

0
0

I don't think that spliting code with if/else is a good approach.

Think a long time term. What are you going to do with further versions?. )

How user code can end up being along the time?

For minor versions or reviews, to keep compatibility is expected. @Deprecated comes with comment asking for to developer to don't use that code. It also suggest what component/method/class should used instead. Finally many of them inform that deprecated code wont be supported in further versions. Or might not be supported (they don't know yet).

However on new versions (major change-redesign) does not make too much sense to keep deprecated code because it make maintainance harder. Legacy code also can be afected by the changes made. Directly or not.

It also makes unclear the usage. Even if deprecated code is annotated.

If your case is a real major change or revamp I would rather encourage/force users to move to the new feature.

If new lib looks unestable user can downgrade the dependency and stick on it till new lib bugs are solved.

As developer I expect changes from one version to another. If I decide to use the new one I accept to deal with such changes.

At the worse scenario, I can switch back to the previous.

I would not lay on expressions like 'is temporal'. Because we all know how it ends up...

Rather to prevent to the user to fall in such afirmations that ends up in code hard to read and hard to maintain

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.