Reputation: 1872
Suppose I have created a library and distribute all over the company and it use in every project.
Library is 1.0 and Suppose I have a interface Componentble.
public interface Componentble {
public String getComponentId();
}
I had done some modification and updated the jar for 1.1 and Componentble interface modified as follows.
public interface Componentble {
public String getComponentId();
public Componentble getParentComponent();
}
When this jar applied to existing project it will gives compile errors. I want to do this modifications and update the jar. but case is it should not affect to existing projects.
What is the best way to do this. Create ComponentbleV2 and in new project ask to use ComponentbleV2 not Componentble.
Or Create custom class loader and do what need.
The answer what i want is how we can do api modification and apply to existing project with out any compilation issue for existing projects.
Upvotes: 1
Views: 134
Reputation: 404
There is no need to deprecate the old one. Create two interfaces where the new one extends the old one.
public interface Componentble {
public String getComponentId();
}
and
public interface ComponentbleWithStructure extends Componentble {
public Componentble getParentComponent();
}
Implementing a interface should imply that the implementer follows the contract of that interface.
This way you know that any class implementing both has been remade to fit the new contract and the ones implementing only the old still follows the old contract.
Example of use:
void doStuff(Componentble component){
if(component instanceof ComponentbleWithStructure){
Componentble parent=((ComponentbleWithStructure)component).getParentComponent();
....
}
....
}
The java8 way is only useful when it is possible to express the new functionality using the old interface. For example if you have a service that can look up parents you could write.
public interface Componentble {
public String getComponentId();
public default Componentble getParentComponent() {
return ParentLookUpService.getParent(getComponentId());
}
}
This way you will know that all instances using the new interface have a correct implementation.
Upvotes: 2
Reputation: 2982
From Java 8 on you can provide default implementations for interface methods. They were invented exactly for your problem.
public interface Componentble {
public String getComponentId();
public default Componentble getParentComponent() {
return null;
}
}
Upvotes: 2
Reputation: 5747
One way to do this is by annotating the method(s) in your old interface with @Deprecated and explaining in the javadocs what to use instead.
For more documentation on that, see Oracle documentation on @Deprecated
For the sake of backwards compatibility, you're going to have to keep both interfaces for now. This might require a bit of customization in the implementation of the interfaces. In a while, after you've been through a couple more versions, you can remove the old interface.
Make sure to properly document your deprecated methods, so that the developers who use it know what to use instead and where to find it.
Upvotes: 2