0

现在我的班级看起来像这样:

private boolean hungry;
private boolean sleepy;
private boolean happy;

...

private setState(List<KeyValuePair> pairs) {
   for (KeyValuePair pair : pairs) {
       String key = pair.getKey();
       String value = pair.getValue();

       if (key.equals("hunger") && value.equals("Y")) hungry = true;
       if (key.equals("tired") && value.equals("Y")) sleepy=true;
       if (key.equals("sad") && value.equals("N")) happy = true;
   }
}

这很好,但非常依赖于这个特定的条件逻辑。不幸的是,我无法更改 KeyValuePair 的想法(它是外部的)

让(键,值)对将适当的变量设置为 true 的更稳健的方法是什么?(永远为真,从不假)

我希望它易于阅读+可扩展。

我唯一能想到的就是制作一个Map<Map<String,String>,String>,这很糟糕,特别是因为我必须在运行时静态构建。

有任何想法吗?

4

5 回答 5

1

怎么样:

private setState(List<KeyValuePair> pairs) {
   for (KeyValuePair pair : pairs) {
       String key = pair.getKey();
       String value = pair.getValue();

       hungry = (key.equals("hunger") && value.equals("Y")) || hungry;
       sleepy = (key.equals("tired") && value.equals("Y")) || sleepy;
       happy = (key.equals("sad") && value.equals("N")) || happy;
   }
}

如果它的任何状态曾经评估过,true那么无论其他迭代如何,它都将保持真实。就使这更简单(删除逻辑)而言,鉴于您那里有地图和列表的奇怪混合,我看不出您如何做到这一点。

于 2012-05-04T19:39:23.600 回答
0

只是为了好玩:

import java.util.Comparator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

public class State
{
  public static class KeyValuePair
  {
    private final String key;
    private final String value;

    public KeyValuePair( String key, String value )
    {
      super();
      this.key = key;
      this.value = value;
    }

    public String getKey()
    {
      return this.key;
    }

    public String getValue()
    {
      return this.value;
    }

  }

  public boolean setState( List<KeyValuePair> pairs )
  {
    //
    boolean happy = false;

    //
    final Comparator<KeyValuePair> comparator = new Comparator<KeyValuePair>()
    {
      @Override
      public int compare( KeyValuePair o1, KeyValuePair o2 )
      {
        int compareTo = o1.getKey().compareTo( o2.getKey() );
        if ( compareTo == 0 )
        {
          compareTo = o1.getValue().compareTo( o2.getValue() );
        }
        return compareTo;
      }
    };
    final SortedSet<KeyValuePair> matchingKeyValuePairSet = new TreeSet<KeyValuePair>( comparator );
    matchingKeyValuePairSet.add( new KeyValuePair( "hunger", "Y" ) );
    matchingKeyValuePairSet.add( new KeyValuePair( "tired", "Y" ) );
    matchingKeyValuePairSet.add( new KeyValuePair( "sad", "N" ) );

    for ( KeyValuePair pair : pairs )
    {
      happy |= matchingKeyValuePairSet.contains( pair );
    }

    //
    return happy;

  }

}

JUnit 测试用例:

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.List;

import org.junit.Test;

public class StateTest
{
  private State state = new State();

  @Test
  public void testSetState()
  {
    {
      final List<State.KeyValuePair> pairs = Arrays.asList( new State.KeyValuePair( "hunger", "Y" ) );
      assertTrue( this.state.setState( pairs ) );
    }
    {
      final List<State.KeyValuePair> pairs = Arrays.asList( new State.KeyValuePair( "hunger", "N" ) );
      assertFalse( this.state.setState( pairs ) );
    }
    {
      final List<State.KeyValuePair> pairs = Arrays.asList( new State.KeyValuePair( "hunger", "N" ),
                                                            new State.KeyValuePair( "sad", "N" ) );
      assertTrue( this.state.setState( pairs ) );
    }
  }

}
于 2012-05-04T19:59:35.213 回答
0

KeyValuePair你的工具很有可能equals。如果是这样,你可以写

final KeyValuePair kvHungry = new KeyValuePair("hunger", "Y");
boolean hungry = false;
for (KeyValuePair pair : pairs) hungry |= pair.equals(kvHungry);

其他人也是如此。

于 2012-05-04T20:12:50.613 回答
0

首先,我会创建一个枚举来代表各州,毕竟这就是它们的用途。仅此一项就可以使事情变得更清洁,但是如果您真的想让它更具可扩展性,我会创建一个抽象的 StateResolver 类。它将由 HungerStateerResolver、SleepStateResolver 和 HappynessStateResolver 扩展。然后这些人会有一个解决方法,它会根据我的输入给我一个结果状态。确实,它是可扩展的,但您必须考虑到您将创建一个层次结构,这也有其自身的含义。

于 2012-05-04T19:56:34.333 回答
0

我不认为条件逻辑有什么特别错误的地方。简洁明了。

一种可能性是尝试将其转变为某种数据驱动的设计,但我怀疑这会买多少,因为您设置的变量(hungry等)必须在编译时知道。

于 2012-05-04T19:41:15.783 回答