この答えは+1
さらに、ポリモーフィズムを使用した次の実装をお勧めします。
このように、クラス間の結合を減らすことで、新しいプラットフォームを簡単に追加できます。
クライアントコード:
Desktop desktop = Desktop.getDesktop();
desktop.open( aFile );
desktop.imaginaryAction( aFile );
デスクトップの実装:
package your.pack.name;
import java.io.File;
public class Desktop{
// hide the constructor.
Desktop(){}
// Created the appropriate instance
public static Desktop getDesktop(){
String os = System.getProperty("os.name").toLowerCase();
Desktop desktop = new Desktop();
// This uf/elseif/else code is used only once: here
if ( os.indexOf("windows") != -1 || os.indexOf("nt") != -1){
desktop = new WindowsDesktop();
} else if ( os.equals("windows 95") || os.equals("windows 98") ){
desktop = new Windows9xDesktop();
} else if ( os.indexOf("mac") != -1 ) {
desktop = new OSXDesktop();
} else if ( os.indexOf("linux") != -1 && isGnome() ) {
desktop = new GnomeDesktop();
} else if ( os.indexOf("linux") != -1 && isKde() ) {
desktop = new KdeDesktop();
} else {
throw new UnsupportedOperationException(String.format("The platform %s is not supported ",os) );
}
return desktop;
}
// default implementation :(
public void open( File file ){
throw new UnsupportedOperationException();
}
// default implementation :(
public void imaginaryAction( File file ){
throw new UnsupportedOperationException();
}
}
// One subclass per platform below:
// Each one knows how to handle its own platform
class GnomeDesktop extends Desktop{
public void open( File file ){
// Runtime.getRuntime().exec: execute gnome-open <file>
}
public void imaginaryAction( File file ){
// Runtime.getRuntime().exec:gnome-something-else <file>
}
}
class KdeDesktop extends Desktop{
public void open( File file ){
// Runtime.getRuntime().exec: kfmclient exec <file>
}
public void imaginaryAction( File file ){
// Runtime.getRuntime().exec: kfm-imaginary.sh <file>
}
}
class OSXDesktop extends Desktop{
public void open( File file ){
// Runtime.getRuntime().exec: open <file>
}
public void imaginaryAction( File file ){
// Runtime.getRuntime().exec: wow!! <file>
}
}
class WindowsDesktop extends Desktop{
public void open( File file ){
// Runtime.getRuntime().exec: cmd /c start <file>
}
public void imaginaryAction( File file ){
// Runtime.getRuntime().exec: ipconfig /relese /c/d/e
}
}
class Windows9xDesktop extends Desktop{
public void open( File file ){
//Runtime.getRuntime().exec: command.com /C start <file>
}
public void imaginaryAction( File file){
//Runtime.getRuntime().exec: command.com /C otherCommandHere <file>
}
}
これは単なる例であり、実際には、値(コマンド文字列%s)をパラメータ化するためだけに新しいクラスを作成する価値はありません。しかし、各メソッドがプラットフォーム固有の方法で別のステップを実行することを想像してみましょう。
この種のアプローチを行うと、時間の経過とともにバグが発生する可能性のある不要なif / elseif / elseコンストラクトが削除される可能性があります(コードにこれらが6つあり、変更が必要な場合は、そのうちの1つを更新するのを忘れるか、コピー/貼り付けるコマンドを変更するのを忘れる可能性があります)