我认为下面的代码很难理解。我也觉得它滥用了Java的三元运算符。

String name = ((this.getAllNamesAsDelimitedString().contains(incomingName) ? 
               incomingName:
               (CollectionsUtils.isEmptyCollection(this.getEntityOperationMap()) ? 
               null : 
               this.getEntityOperationMap.get(incomingName))));


getAllNamesAsDelimitedString上方将返回一个以逗号分隔的,(<43 /> 79q)。如果看起来更干净,更容易理解。在SVN中解决合并问题也很容易。

NB:在我刚刚接手的代码中,甚至还有更多的嵌套三元条件。 >是否有一般性建议建议应允许三元运算符的级别数?换句话说,是否有任何建议建议何时中断三元运算符以提高代码可读性?

评论

顺便说一句,与三元运算符没有直接关系,如果地图为空,则Map.get将返回null,因此CollectionsUtils.isEmptyCollection分支完全没有必要。
@PeterTaylor这可能是检查映射是否为空或为空。但是,考虑将空映射与空映射相同并不是最好的主意。

@Sulthan,用新鲜的眼睛看着它,我认为你是对的。但是,如果将它与null进行实际比较,它将具有更多的自我证明,因为这是唯一的真实目的。

@PeterTaylor同意。

在这种情况下,删除它会有所帮助

#1 楼

是的,那是滥用。

一般来说,我在您的代码中看到两点,您可以根据基础数据结构来推断含义,如果要更改的话,这些含义也需要更改。

另外,这些类型的调用(getAllNamesAsDelimitedString().contains(incomingName)(CollectionsUtils.isEmptyCollection(this.getEntityOperationMap())通常最终会被使用很多次,从而导致DRY。

另外,(this.getAllNamesAsDelimitedString().contains(incomingName)违反了demeter法则(它有两个点),并在没有充分理由的情况下将我假设的实体作为字符串公开。

因此,首先,我将(this.getAllNamesAsDelimitedString().contains(incomingName)修改为this.containsName(incomingName)
< br哪个声明:

String name = ((containsName(incomingName)) ? incomingName:
               (CollectionsUtils.isEmptyCollection(this.getEntityOperationMap()) ? 
               null : 
               this.getEntityOperationMap.get(incomingName))));


好一点。

我将相同的重构应用于下一个三元,通过引入hasOperations方法:

 private boolean hasOperations()
 {
     return !CollectionUtils.isEmptyCollection(this.getEntityOperationMap())
 }


现在发表以下声明:

String name = ((containsName(incomingName)) ? incomingName:
               hasOperations() ? this.getEntityOperationMap.get(incomingName)) : null;


再说一遍更好,但仍然令人不快。

最后,我将其换成真正的q4312079 q

 private String getName(String incomingName)
 {
     if (containsName(incomingName))
        return incomingName;
     else 
        return hasOperations() ? getOperation(incomingName) : null;
 }


评论


\ $ \ begingroup \ $
好人之一,非常好,您提到了“得墨meter耳法则” :)
\ $ \ endgroup \ $
–mprabhat
2011年12月5日7:03

\ $ \ begingroup \ $
摆脱最后的三元操作的一种可能是,当没有操作时,getOperation返回null。还是太不透明?
\ $ \ endgroup \ $
–RoToRa
2011-12-5 12:04

\ $ \ begingroup \ $
@RoToRa这取决于您认为getOperation()的约定应该是什么,以及是否没有操作是否返回null或引发异常是否有效。如果可以返回null,则-是-将三元数移到那里似乎是有效的。
\ $ \ endgroup \ $
–马蒂·皮特(Marty Pitt)
2011年12月6日下午0:01

\ $ \ begingroup \ $
考虑到如果没有操作,让getName返回null会很奇怪,但是如果其中的操作和传入名称不是一个(前者是后者的特例),则抛出异常将会已经返回null(尤其是因为它将替换this.getEntityOperationMap.get,而后者确实做到了)。实际上,考虑到它,原始代码首先检查映射是否为空是有点奇怪的,因为这是不必要的。
\ $ \ endgroup \ $
–RoToRa
2011年12月6日上午8:28

\ $ \ begingroup \ $
还有一件事:自从使用Scala以来,在这种情况下我将使用Option类型/单子,因此明确声明它可以返回“ nothing”。
\ $ \ endgroup \ $
–RoToRa
2011年12月6日上午8:29

#2 楼

我认为必须注意,可以将嵌套的三进制运算符设置为看起来不错的格式:

方法调用,但是我认为将条件保持简短和有意义会更好。

评论


\ $ \ begingroup \ $
我完全同意。实际上,我认为嵌套三元运算符是存在的一些最易读的结构!
\ $ \ endgroup \ $
–托德·雷曼(Todd Lehman)
2012年1月22日7:52



#3 楼

在我看来,与使用神秘的三元运算相比,我希望代码更加清晰。如果三元运算符的语句乍一看变得难以理解,那么if.else将是理想的选择。而且,我不知道使用三元运算符在应用程序中有任何性能差异。
在您的代码示例中:花一些时间弄清楚三元运算符的情况,即使缩进正确,代码也不会像if ... else那样明显。

也许您可以从这里的相关讨论中受益。

#4 楼

我完全同意用户@seand-格式改变了世界。我认为您的示例完全不是滥用行为,但我认为对它进行一些小的更改会更容易...

首先,删除不必要的括号:

String name = this.getAllNamesAsDelimitedString().contains(incomingName) ? 
              incomingName:
              CollectionsUtils.isEmptyCollection(this.getEntityOperationMap() ? 
              null : 
              this.getEntityOperationMap.get(incomingName);


接下来,按照@seand的建议重新格式化三元表达式树:和?紧接其前一个字符之后-中间没有空格-好像它们是英文标点符号:
String name = this.getAllNamesAsDelimitedString().contains(incomingName) ? incomingName
            : CollectionsUtils.isEmptyCollection(this.getEntityOperationMap() ? null
            : this.getEntityOperationMap.get(incomingName);


但是在这种情况下,我可能会这样写:

String name = isConditionA? "first":
              isConditionB? "second":
              isConditionC? "third":
                            "fourth";


评论


\ $ \ begingroup \ $
很好。如何获得Eclipse的格式化程序以这种方式格式化代码?
\ $ \ endgroup \ $
–马丁·施罗德(MartinSchröder)
2012年2月21日23:13

\ $ \ begingroup \ $
@MartinSchröder:参见stackoverflow.com/q/8044946/821436
\ $ \ endgroup \ $
–马丁·施罗德(MartinSchröder)
2012年2月22日10:00