3

多分私はCで多くを考えていますが、Javaでこれを適切に解決する方法がわかりません。次のような文字列を送信するサーバーからの応答を受け取ります。

command params <xml...>

クライアントはその文字列を受け取り、コマンドを抽出します。ここで、コマンドの処理方法を知っている関数を呼び出したいと思います。C 側では、解決策は明らかです。コマンド名と関連する関数ポイントを含む配列を実装したので、配列を単純にループして関数を呼び出すことができます。

Javaでもこれを行う方法はありますか?名前に基づいて関数を呼び出すことができるかどうかわかりません。したがって、現在、次のオプションが表示されます。

  1. 一連のことを行うif(command.euqals(COMMAND)
  2. コマンドごとに、配列に格納できる個別のオブジェクトを作成できます (非常に面倒です)。
  3. リフレクションを使用して、関数名とコマンド名のマップを作成できるようにします。

他のオプションはありますか?

if ステートメントは最適な IMO ではありませんが、少なくともコンパイラ エラーと型チェックを可能にします。リフレクションを使用すると、より簡単にループして拡張できるため、少なくともより洗練されていますが、もちろん、名前を間違えると実行時エラーしか表示されないことを意味します。

4

4 に答える 4

1

あなたの2番目のアイデアは慣用的です。a を使用しMap<String, Runnable>てコマンド名と対応するコードを保存し、次にcommands.get(commandName).run()実行します。

クラスの作成を恐れないでください。switchコードがより冗長になる可能性がありますが、クラスを作成する方がはるかに簡単であり、またはで同じことを行うよりも心配する必要はありませんif ... else if ...toString()コマンドが単一のメソッド (おそらく、 ...)よりも複雑になった場合undo()は、条件分岐の代わりにポリモーフィズムを使用してよかったと思うでしょう。

于 2013-08-07T10:10:07.750 に答える
0

私は最近、関数または関数のセットを別の関数で「ラップ」するという、単純ですが非常に効果的な関数のトリックを見せられました。

以下は、このトリックを示すために私が書いたコードの例です。私の例では、1 つのコマンドに対して 1 つの関数しか提供していませんが、必要に応じて一連の関数が返されるように簡単に拡張できます (したがって、使用できる Guava Mutlimap タイプが含まれています)... Optional を返すので、コマンドが一致しない場合、「安全に」null を返します。Contact と ContacUnit はすべて組織タイプを拡張するドメイン タイプです...これにより、以下のコードが意味を持つようになります。

package com.xxx.component;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.xxx.domain.Contact;
import com.xxx.domain.ContactUnit;
import com.xxx.domain.Organization;

import java.util.Optional;
import java.util.function.Function;

/**
 * This serves up the functions used for the domain
 * to validate itself.
 * Created by beezerbutt on 06/04/2017.
 */
public class MapSetDomainFunctionFactory {

    public static final Function<String, Optional<Organization>> toContactFromCwid = s-> Optional.ofNullable(s).map(Contact::new);
    public static final Function<String, Optional<Organization>> toContactUnitFromKey = s-> Optional.ofNullable(s).map(ContactUnit::new);

    public static final Function<String, Function<String, Optional<Organization>>> commandToFunctions = command -> {
        if (command.equalsIgnoreCase("toContactFromCwid")) {
            return MapSetDomainFunctionFactory.toContactFromCwid;
        } else {
            return null;
        }
    };
}

}

作業を楽にするために、Domain クラス コードを含めます。

/**
 * Created by beezerbutt on 06/04/2017.
 */
public class Contact implements Organization {
}
public class ContactUnit implements Organization {
}
public interface Organization {
}

以下は、コードが機能することを証明するために実行した Spock テストのスナップショットです。 ここに画像の説明を入力

于 2017-04-16T11:55:30.843 に答える