0

動的コードを書きたいとしましょう:

ウォークラフト 3 トリガー システム:

Event: if a unit levels
  Condition: if ( triggeringUnit is alive ) && ( triggeringUnit.name="something" )

ジャワ

for ( Unit triggeringUnit : leveledUnits )
{
  condition1 = new IsAliveCondition(triggeringUnit);
  condition2 = new HasNameCondition(triggeringUnit);
  if ( new AndCondition( condition1 , condition2 ).isTrue() )
  {

  }
}

問題 : コードが静的に記述されている場合、このコードは実行されますが、動的に形成することはできません。条件 1,2 を作成するには、コンストラクターに「特定のユニット」が必要なため、メモリに格納することはできません (作成できないため)。この問題が存在する理由: 条件 1,2 は、それが「for ループ」内にあることを認識していません。また、そのスコープに変数「triggeringUnit」があることも知りません。

その問題を解決するには、スコープ内のすべての変数でハッシュマップを作成する必要がありますか?


Hashmap<String, Object> variables = ... ;
   condition1 = new IsAliveCondition("triggeringUnit");
   condition2 = new HasNameCondition("triggeringUnit");
   condition = new AndCondition( condition1, condition2);

   //At Runtime
   for( Unit triggeringUnit : leveledUnits )
   {
      variables.put("triggeringUnit", triggeringUnit );
      if ( condition.isTrue() )
      {

      }
   }


これよりも優れたソリューション/設計パターンはありますか?

4

3 に答える 3

0

動的条件の場合、動的言語を使用できます。以下は、Groovyコンソールで実行できるGroovyのスニペットです。

class IsAliveCondition {
    def triggeringUnit

    boolean isCase() {
        triggeringUnit.alive
    }
}

class HasNameCondition {
    def triggeringUnit
    def name

    boolean isCase() {
        triggeringUnit.name == name
    }
}

class MyUnit {
    def alive
    def name
}

def condition = '''
new IsAliveCondition(triggeringUnit: triggeringUnit) && 
new HasNameCondition(triggeringUnit: triggeringUnit, name: 'somename').isCase()
'''

def leveledUnits = [new MyUnit(alive: true, name: 'somename'), new MyUnit(name: 'Joe')]

leveledUnits.each { triggeringUnit ->
    def shell = new GroovyShell(this.class.classLoader, new Binding([triggeringUnit: triggeringUnit]))
    if (shell.evaluate(condition)) {
        println "Condition for <$triggeringUnit.name> satisfied: $condition"
    }
}

ご覧のとおり、ここでの条件はハードコードされた文字列です。ただし、ファイルから簡単に読み取ることができます。Binding使用したハッシュマップの一種ですが、Groovyから提供されています。

もちろん、JVMには他にも多くの動的言語があります。Jython、JRuby、JavaScriptが主要な言語です。それらは通常、比較的単純なJavaと相互通信します。たとえば、Javaで作成することIsAliveConditionHasNameConditionできます(この場合、コンストラクターとゲッター/セッター、およびタイプ情報が必要になります)。

于 2012-09-13T14:11:34.430 に答える
0

Business Rules Systemsを探しているようです。これらのシステムでは、GUI または一種のスクリプトを使用してルールを作成することができ、言語 (多くの場合 Java) とインターフェースして、ルールにより多くの機能を提供し、プログラムがルール エンジンを呼び出せるようにすることができます。

最もよく知られているフリーでオープンソースの BRMS はDROOLSです。

于 2012-09-13T11:38:51.660 に答える
0

一般に、これにはパブリッシュ/サブスクライブ メカニズム、またはGOF が呼び出すオブザーバー パターンが必要です。イベント タイプの階層を作成し、何かが発生するたびにイベントを発生させて、オブザーバーがサポートされているイベントをサブスクライブできるようにします。

ここに初歩的な最初のドラフトがあります:

interface EventListener<X extends EventType>{
    processEvent(Map<String, Object> data);
}

public class EventDispatcher{
    private Map<EventType, Collection<EventListener<?>> listeners; // initialize this
    public <X extends EventType> void addListener(X type, EventListener<X> listener){
        // add listener to map
    }
    public void dispatchEvent(EventType type, Map<String, Object> data){
        if(listeners.containsKey(type){
            for(EventListener<EventType> listener: listeners.get(type)){
                listener.processEvent(data);
            }
        }
    }
}

これで、レベルアップ イベントが発生すると、データ マップには、レベルアップしたユニットの生存統計と名前統計が含まれます。

于 2012-09-13T12:05:03.550 に答える