用某些东西代替条件?

Replacing conditional with something?

我有以下嵌套的 if 子句,我想知道我是否可以通过应用某种模式来简化它?

代码检查是否需要 authorizationStartDate,如果需要但没有,returns true。

我考虑过策略模式、"Replace conditional with polymorphism" 方法、规范模式和其他各种模式,但我没有找到任何我喜欢的。

private bool IsMissingAuthorizationStartDate(ApplicationStatusData data)
    {
        if (data.ApplicationStatus == ApplicationStatusType.ApplicationApproved)
        {
            if (data.ApplicationPurpose == ApplicationPurpose.New)
            {
                if (data.ProductStatus?.ProductStatusType == ProductStatusType.ApplicationForNewProductReceived)
                {
                    if (data.ApplicationTypePesticide == ApplicationTypePesticide.Authorisation ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.ProvisionalAuthorisation ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.MutualRecognition ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.Derogation ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.DispensationPreviousAssessment ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.ResearchAndDevelopmentPurposesExperimentOrTestProgram ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.ResearchAndDevelopmentPurposesExperimentOrTestProgramKnownProduct ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.ParallelTradePermit ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.Copy
                        )
                    {
                        if (!data.AuthorizationStartDate.HasValue)
                        {
                            return true;
                        }
                    }
                }
            }
            else if (data.ApplicationPurpose == ApplicationPurpose.Renewal)
            {
                if (data.ProductStatus.ProductStatusType == ProductStatusType.ProductAuthorised)
                {
                    if (data.ApplicationTypePesticide == ApplicationTypePesticide.ReAuthorisation ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.ParallelTradePermit ||
                        data.ApplicationTypePesticide == ApplicationTypePesticide.Copy
                        )
                    {
                        if (!data.AuthorizationStartDate.HasValue)
                        {
                            return true;
                        }
                    }
                }
            }
        }

        // else
        return false;
    }

我怀疑您可能想看一下代码中的下一层,事实上它 returning 一个布尔值表明这是在条件下被其他东西使用的。

也就是说,我通常喜欢 chain of responsibility 模式来处理这类事情。但我个人不会 return 布尔值,如果确定负责该类型的数据(即另一个级别),我会让负责的对象执行操作。

只是供你考虑的一个选项,这种东西没有硬性规定。

我在这里使用的模式只是封装。这里的嵌套很难遵循,并且由于相等比较而变得更糟。如果可能,不要暴露原始字段,而是尝试封装 intent

例如尝试使用 属性 扩展 ApplicationStatusData 而不是 if (data.ApplicationPurpose == ApplicationPurpose.Renewal),例如

bool IsRenewalApplication 
{
 get 
 {
  return this.ApplicationPurpose == ApplicationPurpose.Renewal;
 }
}

所以你的代码读起来更清晰,表达更多:if (data.IsRenewalApplication) { ... }

特别是在你有那么大的地方,如果这个或那个或那个或那个,把它放在一个名字很好的 属性 下,比如 IsInterestingPesticide

如果由于某种原因你不能改变ApplicationStatusData,你可以对return布尔值的成员函数做同样的事情,表达相同的意图。

HTH!

PS,您甚至可能想将整个嵌套 if 封装到一个概念中。然后你在 return false.

之前只有 2 个布尔测试

这并不能真正回答您关于设计模式的问题,但您可能仍然感兴趣。 你可以像那样重写你的方法。

前两个数组:

private ApplicationTypePesticide[] typePesticidesNewPurpose
    = new ApplicationTypePesticide[]
{
    ApplicationTypePesticide.Authorisation,
    ApplicationTypePesticide.ProvisionalAuthorisation,
    ApplicationTypePesticide.MutualRecognition,
    ApplicationTypePesticide.Derogation,
    ApplicationTypePesticide.DispensationPreviousAssessment,
    ApplicationTypePesticide.ResearchAndDevelopmentPurposesExperimentOrTestProgram,
    ApplicationTypePesticide.ResearchAndDevelopmentPurposesExperimentOrTestProgramKnownProduct,
    ApplicationTypePesticide.ParallelTradePermit,
    ApplicationTypePesticide.Copy
};

private ApplicationTypePesticide[] typePesticidesRenewalPurpose
    = new ApplicationTypePesticide[]
{
    ApplicationTypePesticide.ReAuthorisation,
    ApplicationTypePesticide.ParallelTradePermit,
    ApplicationTypePesticide.Copy
};

那么你之前的方法就变成了:

private bool IsMissingAuthorizationStartDate(ApplicationStatusData data)
{
    return data.ApplicationStatus == ApplicationStatusType.ApplicationApproved
        && (IsMissingAuthorizationStartDatePart2(data, ApplicationPurpose.New,
                ProductStatusType.ApplicationForNewProductReceived, typePesticidesNewPurpose)
            || IsMissingAuthorizationStartDatePart2(data, ApplicationPurpose.Renewal,
                ProductStatusType.ProductAuthorised, typePesticidesRenewalPurpose));
}

private bool IsMissingAuthorizationStartDatePart2(ApplicationStatusData data,
    ApplicationPurpose purpose, ProductStatusType statusType,
    params ApplicationTypePesticide[] typePesticides)
{
    return (data.ApplicationPurpose == purpose
        && data.ProductStatus.ProductStatusType == statusType
        && statusType.Any(st => data.ApplicationTypePesticide == st)
        && !data.AuthorizationStartDate.HasValue);
}

注意:如果您总是调用此示例中的方法,则可以删除 params 关键字。
您还应该考虑重命名 part2 方法。