2012-08-10 88 views
3

java.lang.Boolean完美地处理三元逻辑,因为它确切地可以有三种状态:Boolean.TRUE(它是这种情况),Boolean.FALSE(它不是这种情况)和空(我们不知道是什么情况)。这将是一个很好的设计来处理这个使用switch语句,例如。在此构造函数中:使用java.lang.Boolean和开关做三位一体逻辑

public class URN { 
private String value = null;  

public URN (String value, Boolean mode){ 
    switch (mode){ 
     case TRUE: 
      if(!isValidURN(value)) 
       throw new MalformedURLException("The string could not be parsed."); 
      this.value = value; 
     break; 
     case FALSE: 
      this.value = value.concat(checkByteFor(value)); 
     break; 
     case null: 
      if(isValidURN(value)) 
       this.value = value; 
      else 
       this.value = value.concat(checkByteFor(value)); 
     break; 
    } 
    return; 
} 

不幸的是,Java不允许抱怨“无法打开布尔类型的值”。实现这导致混淆的控制流和unnice代码:

public URN (String value, Boolean mode){ 
    Boolean valid = null; 
    if (!Boolean.FALSE.equals(mode)){ 
     valid = isValidURN(value); 

     if (Boolean.TRUE.equals(mode) && !valid) 
       throw new MalformedURLException("The string could not be parsed."); 

     if(Boolean.TRUE.equals(valid)) { 
      this.value = value; 
      return; 
    } } 

    this.value = value.concat(checkByteFor(value)); 
} 

做它很好的方式,需要实现一个枚举类(在现实生活中,比这个例子更复杂,因为.equals()必须重写,这样Trinary.NULL.equals(空)为真)和转换:

private enum Trinary {TRUE, FALSE, NULL}; 
public URN (String value, Boolean toConvert, String x){ 

    Trinary mode; 
    if(toConvert == null) 
     mode = Trinary.NULL; 
    else 
     mode = toConvert.equals(Boolean.TRUE) ? Trinary.TRUE : Trinary.FALSE; 

    switch (mode){ 
     case TRUE: 
      if(!isValidURN(value)) throw new MalformedURLException("The string could not be parsed."); 
      this.value = value; 
     break; 
     case FALSE: 
      this.value = value.concat(checkByteFor(value)); 
     break; 
     case NULL: 
      if(isValidURN(value)) 
       this.value = value; 
      else 
       this.value = value.concat(checkByteFor(value)); 
     break; 
    } 
    return; 
} 

在我眼中,这是因为更具有可读性的解决方案更好,但是代码的由来方法大小的另一个半只是为了转换是烦人的,在现实生活中,你必须关心具有相同语义的两个不同的空值。有没有更好的方法来做到这一点?

+0

有人可能会增加一个“三元逻辑”这里的标签:) – Paramaeleon 2012-08-10 07:34:11

+4

其实,这就是所谓的“三元”; - ) – darioo 2012-08-10 07:43:31

+0

更好的方法:不要让'NULL'等于'null',并且首先不要使用'null'。 – 2012-08-10 15:15:04

回答

5

使用空对象传递这样的信息并不是最优的。请记住,您无法对空对象执行任何方法调用,这又意味着如果将来您想要调用任何.getClass,.equals,.compare等,则必须重写您的代码。

你最好的选择是肯定要与枚举选项。

enum Ternary {TRUE,FALSE,UNKNOWN} 

可以进一步拓展类,以便让这样的对象的方法,

public Ternary getByValue(Boolean o) { 
    if(o == null) 
     return UNKNOWN; 
    if(o) 
     return TRUE; 
    return FALSE; 
} 
2

我同意,如果没有提及,它讨厌的开关确实支持null或将其视为default

注意:Trinary可以是NULLnull这可能会令人困惑。

而不是使用true,false和null。我会建议为模式使用有意义的名称。例如使用VALIDATING,CONCATENATING,MIXED或其他更合适的方法。

最简单的解决方案是

public URN (String value, Boolean mode){ 
    if (mode == null) { 
     this.value = isValidURN(value) ? values : value.concat(checkByteFor(value)); 
    } else if (mode) { 
     if(!isValidURN(value)) 
      throw new MalformedURLException("The string could not be parsed."); 
     this.value = value; 
    } else { 
     this.value = value.concat(checkByteFor(value)); 
    } 
    return; 
} 

BTW与TRUE比较容易造成混淆。

Boolean b = new Boolean(true); 
if (b == Boolean.TRUE) // is false !!!