我在搜索设计时如何实现大量计算,以便代码看起来干净并且可以进行单元测试。这就是我现在这样做的方式。
我有块General,MainEngine,AuxEngine,Boilers,WaterBoilers等表格。 每个街区都有很多属性。现在我的计算课看起来像这样。
我在块之间使用部分类来分别计算逻辑
/// <summary>
/// My result class wich fill CalculationResult
/// </summary>
public partial class CalculateBlocks
{
private readonly IClassificatoryService _classificatoryService;
private readonly IReportService _reportService;
public CalculationResult Result = new CalculationResult();
/// <summary>
/// Ctor with DI
/// </summary>
public CalculateBlocks(IClassificatoryService classificatoryService,IReportService reportService)
{
_classificatoryService = classificatoryService;
_reportService = reportService;
}
public void Calculate()
{
CalculateGeneral();
CalculateMainEngine();
//and a lot more blocks
}
}
public partial class CalculateBlocks
{
private void CalculateGeneral()
{
Result.General.TotalReports = 2 + 2;
}
}
public partial class CalculateBlocks
{
private void CalculateMainEngine()
{
Result.MainEngine.Power = 1000;
}
}
我的实体看起来像这样
public class CalculationResult
{
public CalculationResult()
{
General = new General();
MainEngine = new MainEngine();
}
public General General { get; set; }
public MainEngine MainEngine { get; set; }
}
public class General
{
public decimal? TotalReports { get; set; }
//... more here
//... more here
//... more here
}
public class MainEngine
{
public decimal? Power { get; set; }
//... more here
//... more here
//... more here
}
答案 0 :(得分:5)
听起来像strategy pattern就是你要找的东西。每个块都是一个实现接口的单独类。
类似的东西:
interface IBlockCalculator
{
CalculationResult Calculate();
}
class MainEngineBlockCalculator : IBlockCalculator
{
public CalculationResult Calculate()
{
// Calculation goes here...
}
}
class GeneralEngineBlockCalculator : IBlockCalculator
{
public CalculationResult Calculate()
{
// Calculation goes here...
}
}
然后,您可以为每个块实现接口。您甚至可以组合它们,以便您可以使用子块的顶级块。
单元测试也得到了简化,因为您可以单独测试每个单独的块计算。
[Test]
public void TestMainEngineBlock...()
{
// Arrange
var sut = new MainEngineBlockCalculator();
// Set up your test scenario here...
// Act
var actualResult = sut.Calculate();
// Assert
// Assertion on actualResult go here...
}
答案 1 :(得分:0)
您可能需要考虑的另一个概念是Facade design pattern。更为人所知的是为子系统中的一组接口提供统一的接口。在你的情况下
所以代码看起来干净,可以单元测试。
我认为它可用于定义更高级别的实现,使子系统更易于使用。
隐藏实现细节也是Encapsulation的概念。因此,其他用户/ cilents将被提供他们需要知道/使用的东西,实际的处理由负责它的人负责。
如果您打算处理细粒度的实例并分享它们Flyweight design pattern也很有用。