我希望在我的富域模型中使用全局/应用程序级别设置。
我有一个方法,根据传递的参数进行一些计算。
这可能不是最好的示例,可能看起来不像属于域模型的方法,但我尝试保持简单,以便您可以理解问题。
public decimal Calculate(CalculationMethod calculationMethod)
{
switch (calculationMethod)
{
case CalculationMethod.Multiply:
return _x * _y; // _x and _y are fields
case CalculationMethod.Divide:
return _x / _y;
}
}
现在让我们说我在其他域模型中有很多这样的方法,它们也接受CalculationMethod
的方法。我想有一个全局设置,所以我可以全局设置一个计算方法,所以它可以被所有将它作为参数的方法使用。
一种解决方案是每次调用此方法时读取配置。
我想知道是否有更好的方法所以我可以设置CalculationMethod
全局并且永远不会传递它,而是使用某种静态变量(单例)来保存计算方法并直接在我的方法中读取它而不传递它。但我认为那时会出现线程安全问题。
public decimal Calculate()
{
// or read it from file here?
switch (GlobalSettings.CalculationMethod)
{
case CalculationMethod.Multiply:
return _x * _y; // _x and _y are fields
case CalculationMethod.Divide:
return _x / _y;
}
}
我无法在构造函数中传递它,因为它不属于我的域模型。
如何处理这类问题?有没有比我提到的两个更好的方法?
我在Mark Seemann的回答中提出了这个问题:App-level settings in DDD?
正如Clean Code所解释的那样,将标志传递给方法通常被认为是次优设计。我知道OP是另一个更复杂的问题的替身,但我倾向于建议重构一个多态对象模型:
public interface ICalculator
{
decimal Calculate();
}
您现在可以根据需要定义实现:
public class Multiplier : ICalculator
{
public decimal Calculate()
{
return _x * _y; // _x and _y are fields
}
}
public class Divider : ICalculator
{
public decimal Calculate()
{
return _x / _y;
}
}
您可以使用构造函数注入将ICalculator
对象注入任何需要它的类中。在Composition Root中,您可以读取配置文件,或以其他方式决定使用哪个实现,然后只创建该类的单个实例。这为对象提供了Singleton生命周期,因此计算方法在启动时完全选择,并在应用程序中的所有对象之间共享。