首页 > 解决方案 > 默认构造函数在不需要时不必要地初始化依赖项

问题描述

我有两种类型,即AdditionCalcAggregateCalc两种方法:

  1. 计算:返回模型。没有版本代码。
  2. 计算:不返回任何东西。包括版本控制代码。将数据存储在数据库中。

代码 :

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)
    {
    }
}

标签: c#

解决方案


您的两个计算器类不应相互关联。它们应该实现一个通用接口,但不共享通用逻辑。

因此,您将拥有一个支持版本控制的类,以及一个对版本控制一无所知的类。每个人都 100% 专注于自己的逻辑,并且不必与对方耦合/相关或交互。

如果您以后确实有一些常见行为,请确保它确实是常见行为并将其放在您的两个类都继承的基类中。

正如您现在所拥有的那样,您正在覆盖版本控制行为(甚至不是完全)。当您使用继承时,您希望添加功能,而不是减去它们,这就是您当前模型正在做的事情。

查看SOLID以获得更多指导。

考虑,

interface ICalculator
{
    void Calculate() { ... }
}

abstract class CalculatorThatCaresAboutVersion : ICalculator
{
    void CalculatorThatCaresAboutVersion(IVersion version) { ... }
}

abstract class CalculatorThatDoesntCareAboutVersion : ICalculator
{
    void CalculatorThatDoesntCareAboutVersion() { ... }
}

您有两种不知道或不关心其他类型的计算器。如果需要,您可以从它们继承,并且与版本关联的操作与其他计算器中的操作没有任何关系。

这使您可以根据需要自由地实施每一个而不影响另一个:没有诸如“如果我不关心它,我如何不初始化版本?”之类的问题。因为关注点是自然分离的,所以这个问题甚至永远不会出现


推荐阅读