用某些东西代替条件?

时间:2016-12-21 14:15:23

标签: c# design-patterns polymorphism conditional strategy-pattern

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

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

我已经考虑了策略模式,“用多态替换条件”方法,规范模式和其他各种方法,但我没有找到任何我喜欢的东西。

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;
    }

3 个答案:

答案 0 :(得分:1)

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

那说我通常喜欢这种事情的chain of responsibility模式。但我个人不会让它返回一个布尔值,如果确定负责该类型的数据(即另一个级别),我会让责任对象执行一个动作。

只是你可以考虑的一个选择,对于这种事情,没有一条硬性规定。

答案 1 :(得分:1)

我在这里使用的模式只是封装。这里的嵌套很难遵循,并且通过平等比较而恶化。如果可能,请尝试封装 intent ,而不是公开原始字段。

e.g。而不是if (data.ApplicationPurpose == ApplicationPurpose.Renewal)尝试使用

等属性扩展ApplicationStatusData
bool IsRenewalApplication 
{
 get 
 {
  return this.ApplicationPurpose == ApplicationPurpose.Renewal;
 }
}

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

特别是如果您拥有那个或那个或那个或那个那么大,将它放在一个名为IsInterestingPesticide的名称很好的属性下。

如果由于某种原因无法更改ApplicationStatusData,则可以对返回布尔值的成员函数执行相同的操作,表达相同的意图。

HTH!

PS,您甚至可能希望将整个嵌套ifs封装到一个概念中。然后,在返回false之前,您只需要进行2次布尔测试。

答案 2 :(得分:0)

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

前两个数组:

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方法。