C# 用某物替换条件?

C# 用某物替换条件?,c#,design-patterns,polymorphism,conditional,strategy-pattern,C#,Design Patterns,Polymorphism,Conditional,Strategy Pattern,我有下面的嵌套if子句,我想知道我是否可以通过应用一些模式来简化它 代码检查是否需要authorizationStartDate,如果需要,但没有,则返回true 我考虑过策略模式、“用多态性替换条件”方法、规范模式和其他各种模式,但我没有发现任何我喜欢的 private bool IsMissingAuthorizationStartDate(ApplicationStatusData data) { if (data.ApplicationStatus == Appl

我有下面的嵌套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;
    }

我猜想您可能想看看代码中的下一个级别,它返回布尔值这一事实表明它正被其他东西在条件中使用

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


只是一个选项,让你考虑一下,这类事情没有一个硬性的规则。

< P>我在这里使用的模式就是封装。这里的筑巢很难遵循,并且由于平等比较而恶化。如果可能,不要公开原始字段,而是尝试封装意图

e、 g.不要使用if(data.ApplicationPurpose==ApplicationPurpose.Renewal)尝试使用以下属性扩展
ApplicationStatusData

bool IsRenewalApplication 
{
 get 
 {
  return this.ApplicationPurpose == ApplicationPurpose.Renewal;
 }
}
因此,您的代码读起来更干净,有更多的表达式:
if(data.IsRenewalApplication){…}

特别是当你有大量的,如果这个或那个或那个,把它放在一个有名的属性下,比如
IsInterestingElectronics

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


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

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

前两个阵列:

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

一个显而易见的问题是,该方法不符合tin上的说明。如果它按照它在锡上说的做,它将是一行长:
return!data.AuthStartDate.HasValue一个更普遍的问题是,您将业务策略编码到源代码中的方式无法通过编程操作。如果你的程序是关于策略评估的,那么制作一个策略对象图,知道如何评估策略是否满足或违反;代码必须与它所代表的策略一样复杂。相反,我更关心的是当政策改变时会发生什么,就像不可避免的政策一样。@EricLippert:没错,我担心的是,如果/当这些规则改变时,很难理解条件中的不同分叉代表什么样的情况。现在,业务规则在excel工作表中进行了描述,找出哪种情况需要开始日期并非易事。