如何重构这个 Java 代码片段

Posted

技术标签:

【中文标题】如何重构这个 Java 代码片段【英文标题】:How to refactor this Java snippet 【发布时间】:2021-07-15 00:26:35 【问题描述】:

出于某种原因,我不禁在这段代码中看到了冗余。谁能帮我重构它,使其更具可读性和简洁性?

if (cachedParty == null || !cachedParty.equals(partyDto)) 
    if (cachedParty == null 
        && partyDto.getSellerStatusCode()
            .equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode())) 
    
        pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
     else if (!cachedParty.equals(partyDto) 
        && cachedParty.getSellerStatusCode()
            .equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode()) 
        && !partyDto.getSellerStatusCode()
            .equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode())
    ) 
        pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
    
                                
    partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
    partiesToSaveOrUpdate.add(partyDto);

【问题讨论】:

您可以使用很多临时中间变量来简化 - 例如final boolean isPartyDtoActive = ...。此外,只有最后两行需要在初始条件块中,其余部分具有独立检查。 标题含糊。重写以总结您的具体技术问题。 【参考方案1】:
    SellerStatusEnum.ACTIVE 的比较可以实现为接受Supplier<String> 的函数 可以简化***比较以删除cachedParty == null - 从代码中假定partyDto 不为空,因此检查!partyDto.equals(cachedParty) 就足够了

一个示例实现:

Function<Supplier<String>, Boolean> active = x -> SellerStatusEnum.ACTIVE.getCode().equalsIgnoreCase(x.get());

if (!partyDto.equals(cachedParty)) 
    boolean partyActive = active.apply(partyDto::getSellerStatusCode);
    if (null == cachedParty && partyActive 
        || null != cachedParty && !partyActive && active.apply(cachedParty::getSellerStatusCode)
    ) 
        pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
    
    partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
    partiesToSaveOrUpdate.add(partyDto);

【讨论】:

【参考方案2】:

我建议创建返回 partyDto.getSellerStatusCode().equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode() 的辅助方法 isActive(party)。另外,cachedParty == null 时可能存在 NPE,因为!cachedParty.equals(partyDto) 正在为null 调用equals。所以,考虑到partyDto 永远不是null,这可以简化为!partyDto.equals(cachedParty)

另外,您在if(x) else if (y) 语句中调用了相同的方法,因此可以通过x or y 检查将其简化为一个if 语句。所以,让我们重写你的陈述:

if (A or B) 
    if ((A and C) or (B and D and !C))  F() 

    G()


正如我们在第一段中决定的那样,A or B = B。所以表达式现在看起来像

if (B) 
    if ((A and C) or (B and D and !C))  F() 

    G()


// and because inside first if statement B = true, we can remove B from nested if:

if (B) 
    if ((A and C) or (D and !C))  F() 

    G()


所以,通过进行这些优化,我们可以得到:

if (!partyDto.equals(cachedParty)) 

    if (cachedParty == null && isActive(partyDto) || (isActive(cachedParty) && !isActive(partyDto)) 
        pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
    

    partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
    partiesToSaveOrUpdate.add(partyDto);

我注意到您的嵌套 if 中没有 cachedParty != null 签入,因此最终结果将如下所示:

if (!partyDto.equals(cachedParty)) 
    if (cachedParty == null && isActive(partyDto) || (cachedParty != null && isActive(cachedParty) && !isActive(partyDto)) 
        pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
    

    partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
    partiesToSaveOrUpdate.add(partyDto);

【讨论】:

以上是关于如何重构这个 Java 代码片段的主要内容,如果未能解决你的问题,请参考以下文章

java代码在片段活动中不起作用

java 简单的代码片段,展示如何将javaagent附加到运行JVM进程

如何将这个 Objective-C 代码片段写入 Swift?

如何在 Kotlin 片段内的按钮之间切换片段?

哈斯克尔。我很困惑这个代码片段是如何工作的

append() 在这个代码片段中是如何工作的?与特定变量混淆[重复]