15

我想重构以下代码以避免 if...else 这样我就不必在每次新的调查类型出现时都更改方法(打开/关闭原则)。以下是我正在考虑重构的一段代码:

if (surveyType == SurveySubType.Anonymous)
{
    DoSomething(param1, param2, param3);

}
else if (surveyType == SurveySubType.Invitational)
{
    DoSomething(param1);
}
else if (surveyType == SurveySubType.ReturnLater)
{    
    DoSomething(param1);
}

为了解决这个问题,我添加了以下类:

    public abstract class BaseSurvey
{
            public string BuildSurveyTitle()
            {
             ...doing something here
            }

    public abstract void DoSomething(int? param1,int?  param2,int?  param3);
}
public class InvitationalSurvey: BaseSurvey
{
    public override void DoSomething(int? param1,int?  param2,int?  param3)
    {
    //I don't need param2 and param3 here

    }
}


public class ReturnLaterSurvey: BaseSurvey
{
    public override void DoSomething(int? param1,int?  param2,int?  param3)
    {
    //I don't need param2 and param3 here

    }
}


public class AnonymousSurvey: BaseSurvey
{
    public override void DoSomething(int? param1,int?  param2,int?  param3)
    {

    //I need param2 and param3 here
    //do something
    }

}

这就是我的代码的最终结果:

var survey = SurveyFactory.Create();
survey.DoSomething(param1,param2,param3);

我的问题是避免将 param2 和 param3 传递给 InvitationalSurvey 和 ReturnLaterSurvey 类有什么好处?

4

6 回答 6

18

如果param2param3是 的具体要求AnonymousSurvey它们不应该是接口的一部分,而是具体类的一部分:

public abstract class BaseSurvey
{
    public abstract void DoSomething(param1);
}

public class InvitationalSurvey: BaseSurvey
{
    public void DoSomething(param1)
    {
    }
}


public class ReturnLaterSurvey: BaseSurvey
{
    public void DoSomething(param1)
    {
    }
}


public class AnonymousSurvey: BaseSurvey
{
    private readonly object param2;
    private readonly object param3

    public AnonymousSurvey(param2, param3)
    {
        this.param2 = param2;
        this.param3 = param3;
    }

    public void DoSomething(param1)
    {
        // use this.param2 and this.param3 here
    }
}
于 2014-03-27T07:39:57.003 回答
3

为什么不添加重载

doSometing(Param1){
 doSomething(Param1, null, null)
}
于 2014-03-27T05:01:08.133 回答
2

这似乎是一个案例Overloading,但它已经被建议了。因此,作为替代方案,您为什么不这样做,这意味着为参数分配默认值 使其成为可选的。看看下面的例子。

我演示了一个整数类型,您可以更改类型并设置最适合您的默认值。

现场演示

using System;

public class Test
{
    public static void Main()
    {
        // your code goes here
        InvitationalSurvey iservey = new InvitationalSurvey();
        iservey.DoSomething(1, 1, 1);
        iservey.DoSomething(1);
    }
}

public abstract class BaseSurvey
{
     
}
public class InvitationalSurvey: BaseSurvey
{
    public void DoSomething(int param1, int param2 = 0, int param3 = 0)
    {
    //I don't need param2 and param3 here
    Console.WriteLine(string.Format("{0},{1},{2}",param1, param2, param3));
    }
}
于 2014-03-27T05:25:20.940 回答
2

这将有助于了解参数类型是什么。如果它们都相同,那么您至少可以在 C# 中使用params关键字并根据需要发送尽可能多的参数。如果没有,那么您可能想要传递一个参数字典,然后将其留给实现类以将对象转换为正确的类型。

public abstract class BaseSurvey
{
    public abstract void DoSomething(params string[] parameters);
}

public abstract class BaseSurvey
{
    public abstract void DoSomething(Dictionary<string,object> parameters);
}

也许更好的方法是将参数合并到工厂方法调用中,并让工厂在创建时将值设置为正确的类型,然后您可以在没有任何参数的情况下调用该方法。

var survey = surveyFactory.CreateAnonymousSurvey(param1, param2, param3);
survey.DoSomething();

var survey = surveyFactory.CreateReturnLaterSurvey(param1);
survey.DoSomething();
于 2014-03-27T05:05:33.660 回答
1

您发布的代码不是。无论如何,听起来你想要一个Option 类型

于 2014-03-27T04:57:56.500 回答
1

你可以有另一个抽象类扩展BaseSurvey,它InvitationalSurveyReturnLaterSurvey两者都扩展。这个抽象类可以DoSomething(param1,param2,param3)通过调用它自己的抽象方法来实现DoSomething(param1),它可以扩展InvitationalSurvey而不是ReturnLaterSurveyDoSomething(param1,param2,param3)

public abstract class BaseSurvey
{
    public abstract void DoSomething(param1, param2, param3);
}

public abstract class SpecialSurvey : BaseSurvey
{
    public abstract void DoSomething(param1);

    public void DoSomething(param1, param2, param3)
    {
        DoSomething(param1);
    }
}

public class InvitationalSurvey: SpecialSurvey
{
    public void DoSomething(param1)
    {
         ReallyDoSomething();
    }
}
于 2014-03-27T04:57:58.517 回答