2012-04-12 6 views
0

私はcommand design patternを使用してオブジェクトのコレクションを持っています。すなわち、抽象的なCommandクラスを実装し、​​メソッドを持っています。あなたはこのような何かを行うことができ、コマンドラインから(例えば)と呼ばれるコマンドデザインパターンを使用してコマンドラインパラメータをオブジェクトに変換する

、が、その真剣不格好、あなたはこれを実装する方法を:

public void main(String[] arg) { 
    Command c = null; 

    if(arg[0].equals("FirstCommand") { 
     c = new FirstCommand(arg[1]); 
    } 
    if(arg[0].equals("SecondCommand") { 
     c = new SecondCommand(arg[1], arg[2]); 
    } 
    if(arg[0].equals("ThirdCommand") { 
     c = new ThirdCommand(arg[1], Long.parseLong(arg[2])); 
    } 
    //.....etc.... 
    c.execute(); 
} 

明らかに使用可能なコマンドの一覧が大きくなるにつれ、この

答えて

1

反射が容易です。これで起動します。

final Class[] argTypes = new Class[args.length - 1]; 
final String[] cmdArgs = new String[args.length - 1]; 
for (int i = 0; i < argTypes.length; i++) { 
    argTypes[i] = String.class; 
    cmdArgs[i] = args[i+1]; 
} 
final Command c = (Command) Class.forName(MY_PACKAGE + args[0]).getConstructor(argTypes) 
    .newInstance(cmdArgs); 

、修正するための唯一のものは、あなたのCommandコンストラクタに構文解析と検証をプッシュする必要がしようとしているということです。あるいは、あなたが欲しいのであれば、arg countだけに基づいてコンストラクタを見つけることができます。また、どのarg型が受け入れられるかを調べ、適切にcmdline argsを解析します。

0

利用可能なコマンドを追跡する必要のない汎用ソリューションは、コマンドのインスタンス化に反射を使用することです。コンストラクタにパラメータのリストを渡すか、McDowellのようにexecuteメソッドを定義します。これは、同じ引数で同じコマンドを何度も再実行したいのか、そしてコマンドがキャッシュされた結果(ステートフルかステートフルか)から利益を得られるかどうかによって異なります。

コマンド名は、クラスの単純な名前になります。パッケージを追加して完全修飾名を作成し、class.getConstructor(Class [] params)を呼び出してそのコンストラクタを呼び出します(または、executeメソッドにパラメータを渡す場合はデフォルトコンストラクタを使用します)。

+0

複雑なクラスパスのロードハッキングがなければ、これを行うことはできません。 – Jacob

+0

classpath hackeryはどういう意味ですか?私の答えは、パラメータとして指定されたクラスが実行中のクラスのクラスローダに利用可能であることを前提としています。 Marko TopoInikは私が答えを書くのが面倒すぎるコードを掲示しました – bennidi

関連する問題