我想重构以下代码以避免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类会有什么好处?
答案 0 :(得分:17)
如果param2
和param3
是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
}
}
答案 1 :(得分:3)
为什么不添加重载
doSometing(Param1){
doSomething(Param1, null, null)
}
答案 2 :(得分: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();
答案 3 :(得分: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));
}
}
答案 4 :(得分:1)
您发布的代码不是c#或java。无论如何,听起来你想要一个Option type。
答案 5 :(得分:1)
您可以使用另一个扩展BaseSurvey
的抽象类,其中InvitationalSurvey
和ReturnLaterSurvey
都会延伸。这个抽象类可以通过调用自己的抽象方法DoSomething(param1,param2,param3)
来实现DoSomething(param1)
,InvitationalSurvey
和ReturnLaterSurvey
可以扩展DoSomething(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();
}
}