How can I design my Java / C# library so it stays binary compatible in case of future changes?
Task: I am designing a library which will be used by developers.
Objective: I need to make sure that changes in future versions will not impact existing developers.
Example:
Situation during first release:
There is one class
public class ClassSample
{
String methodSample(String para1,String Para2, int Para3, String Para4);
}
Situation during second release:
Requirements:
Response of methodSample can return multiple values.
More parameters are needed in methodSample method.
Solution: One way could be just add another overloaded method which will have new parameters and return object rather than built-in data type.
But problem with above solution is, it will have too many overloaded methods in future, too many parameters will be overkill.
Modified Solution 1:
void methodSample(Request request, Response response)
In each release(obviously if required), I will modify Request & Response classes to have new additional methods to get/set values. There will be a problem in this case as inside the method, I won't be able to differentiate whether caller is of Version10 or Version20.
Modified Solution 2:
void methodSample(AbsractRequest request, AbstractResponse response)
In each release we can extend derived class like Request200 extends Request100 extends AbstractRequest, similarly for response classes. In this case I can check inside method whether caller is of Version10 or Version20 by checking instance typing.
In summary Modified Solution 2 looks good to me, what about your thoughts开发者_如何学Python ?
I would go for Modified Solution 1, but with the addition of a get/set Version method in the class.
Your library can the use getVersion find out which behaviour the user program is expecting
I realise this might be a bit late but thought might be useful to you or someone else.
I've created an SDK in the past that required versioning and did something very similar to what I posted below and it worked a treat.
The idea being that all messages derive from an abstracted class as you suggested, but there is a static that is set in the calling application right at the start. All requests then simply set a Version property equal to that of the static. This way its only specified once in the whole application.
When you add new versions, just add to the enum. I actually used an integer in mine and incremented it but I think an Enum is always more maintainable.
Enjoy!
namespace SilverlightClassLibrary1
{
public enum SDKVersions
{
NonSpecific = 0,
Version100,
Version200,
}
public abstract class RequestBase
{
public static SDKVersions SystemSDKVersion { get; set; }
public SDKVersions RequestSDKVersion { get; set; }
protected RequestBase()
{
this.RequestSDKVersion = RequestBase.SystemSDKVersion;
}
}
public class SimpleDataRequest : RequestBase
{
public String Data { get; set; }
}
public class SimpleDataResponse
{
public String Response { get; set; }
}
public class SomeSDKFunctionality
{
public static void RandomSDKFunction(SimpleDataRequest request, out SimpleDataResponse response)
{
switch (request.RequestSDKVersion)
{
case SDKVersions.Version100:
//Legacy response
response = new SimpleDataResponse()
{
Response = "Helo " + request.Data,
};
break;
default:
//Fixed / Updated Response
response = new SimpleDataResponse()
{
Response = "Hello " + request.Data + "!",
};
break;
}
}
}
}
namespace MyExternalApplication
{
public class Main
{
public void ApplicationEntryPoint()
{
//Specify a specific version you intend to use
RequestBase.SystemSDKVersion = SDKVersions.Version100;
}
public void ButtonClickExample()
{
SimpleDataResponse response;
SomeSDKFunctionality.RandomSDKFunction(new SimpleDataRequest()
{
Data = "James",
}, out response);
}
}
}
精彩评论