c# - 默认构造函数在不需要时不必要地初始化依赖项
问题描述
我有两种类型,即AdditionCalc
有AggregateCalc
两种方法:
- 计算:返回模型。没有版本代码。
- 计算:不返回任何东西。包括版本控制代码。将数据存储在数据库中。
代码 :
public abstract class BaseCalculator
{
private readonly IVersion _version;
protected BaseCalculator(IVersion version)
{
this._version = version;
}
public void Calculate(Request r)
{
CalculateInternal();
//version code here
}
protected abstract void CalculateInternal(Request r);
public abstract StatisticsModel Calculate(StatisticsRequest model);
}
public class AdditionCalc : BaseCalculator
{
public AdditionCalc() : base(new Version(ConfigurationManager.ConnectionStrings["dbConnectionString"].ConnectionString)) { }
public override StatisticsModel Calculate(StatisticsRequest model)
{
//no version code here
}
}
public class CalculatorFactory
{
public BaseCalculator GetCalculatorByType(int type)
{
switch (type)
{
case (int)Types.Addition:
return new AdditionCalc();
case (int)Types.Aggregate:
return new AggregateCalc();
}
}
}
现在的问题是当我调用Calculate
返回的方法时StatisticsModel
,我不想调用基本构造函数,因为对于这个方法我不需要版本代码,但是每次我调用这个方法时,都会调用默认构造函数并初始化version variable of base class
.
这就是我调用适当Calculate
方法的方式:
var calculatorFactory = new CalculatorFactory();
var type = calculatorFactory.GetCalculatorByType((int)Types.Addition);
type.Calculate(StatisticsRequest);
注意:我不想通过调用代码传递版本依赖。
那么我该如何设计上面的代码,以便不会为Calculate
返回的方法调用版本代码StatisticsModel
呢?
更新 :
public class AdditionCalc : BaseCalculator
{
public AdditionCalc() : base(new Version(ConfigurationManager.ConnectionStrings["dbConnectionString"].ConnectionString)) { }
public override StatisticsModel Calculate(StatisticsRequest model)
{
//no version code here
}
protected override void CalculateInternal(Request r)
{
}
}
public class AggregateCalc : BaseCalculator
{
public AggregateCalc() : base(new Version(ConfigurationManager.ConnectionStrings["dbConnectionString"].ConnectionString)) { }
public override StatisticsModel Calculate(StatisticsRequest model)
{
//no version code here
}
protected override void CalculateInternal(Request r)
{
}
}
解决方案
您的两个计算器类不应相互关联。它们应该实现一个通用接口,但不共享通用逻辑。
因此,您将拥有一个支持版本控制的类,以及一个对版本控制一无所知的类。每个人都 100% 专注于自己的逻辑,并且不必与对方耦合/相关或交互。
如果您以后确实有一些常见行为,请确保它确实是常见行为并将其放在您的两个类都继承的基类中。
正如您现在所拥有的那样,您正在覆盖版本控制行为(甚至不是完全)。当您使用继承时,您希望添加功能,而不是减去它们,这就是您当前模型正在做的事情。
查看SOLID以获得更多指导。
考虑,
interface ICalculator
{
void Calculate() { ... }
}
abstract class CalculatorThatCaresAboutVersion : ICalculator
{
void CalculatorThatCaresAboutVersion(IVersion version) { ... }
}
abstract class CalculatorThatDoesntCareAboutVersion : ICalculator
{
void CalculatorThatDoesntCareAboutVersion() { ... }
}
您有两种不知道或不关心其他类型的计算器。如果需要,您可以从它们继承,并且与版本关联的操作与其他计算器中的操作没有任何关系。
这使您可以根据需要自由地实施每一个而不影响另一个:没有诸如“如果我不关心它,我如何不初始化版本?”之类的问题。因为关注点是自然分离的,所以这个问题甚至永远不会出现。