I develop a Java library which shall run on two different platforms. To print messages, one platform uses printA(str)
method, while another uses printB(str)
method. In C++, I'd create a static method:
public static void print(string str)
{
#ifdef platformA
printA(str);
#else
printB(str);
#endif
}
Since Java has no #ifdef
, it becomes a tricky task. I started to look at overriding abstract class with a static method, but not sure I go the right direction. What is the most elegant way to do that?
Edit: With answer of Andy Thomas (thanks!) I found the solution that suits me. The only drawback - it must be initialized on startup. Below is the code. Common library:
//interface is only for internal use in Output class
public interface IPrintApi
{
public void Print(String message);
}
public abstract class Output
{
private static IPrintApi m_api;
public static void SetPrintAPI(IPrintApi api)
{
m_api=api;
}
public static void MyPrint(String message)
{
m_api.Print(message);
}
}
Calling of this function is the same in common library and platform-specific code:
public class CommonTest
{
public CommonTest()
{
Output.MyPrint("print from library");
}
}
Code for each platform has to have the platform specific implementation of the interface, e.g. platformA (for B it is identical):
public class OutputA implements IPrintApi
{
public void Print(String message)
{
//here is our platform-specific call
PrintA(message);
}
}
Usage:
public class AppPlatformA
{
public static void main(String[] args)
{
// point the abstract Output.Print function to the available implementation
OutputA myPrintImpl = new OutputA();
Output.SetPrintAPI(myPrintImpl);
// and now you can use it!
Output.MyPrint("hello world!");
}
}
You could use the strategy pattern.
Define the interface once, and implement it in OS-specific classes.
public interface IPlatformAPI {
public void print( String str );
}
public class WindowsPlatformAPI implements IPlatformAPI {
public void print( String str ) { ... }
}
public class MacPlatformAPI implements IPlatformAPI {
public void print( String str ) { ... }
}
public class LinuxPlatformAPI implements IPlatformAPI {
public void print( String str ) { ... }
}
public class PlatformAPI {
public static IPlatformAPI getPlatformAPI() {
// return one of the platform APIs
// You can use System.getProperty("os.name") to choose the implementation
}
}