在富域模型中使用应用程序级设置 [英] Using app-level settings in rich domain models

查看:80
本文介绍了在富域模型中使用应用程序级设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个要在我的富域模型中使用的全局/应用程序级别设置。

I want to have a global/app level setting that I want to use in my rich domain models.

我有一个方法可以根据传递的参数进行一些计算。

I have a method that does some calculations based on the argument passed.

这可能不是最好的示例,看起来也不像属于域模型的方法,但我尝试使其简单易懂,以便您理解问题。

This might not be the best example and might not look like a method belonging to the domain model but I try to keep it simple so you could understand the problem.

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 的域模型。我想要一个全局设置,以便可以全局设置一个计算方法,以便将其用作参数的所有方法都可以使用。

Now let's say I have many methods like this in my other domain models that also accept CalculationMethod in their methods. I would like to have a global setting so I can set a calculation method globally so it could be used by all methods that take it as a parameter.

一个解决方案是每次调用此方法时都要读取配置。

One solution would be to read the configuration every time I call this method.

我想知道是否有更好的方法,因此可以全局设置 CalculationMethod 并从不通过它,而是一种静态变量(单变量),用于保存计算方法并直接在我的方法中读取它而不传递它。但是我认为那会存在线程安全性问题。

I wonder if there's any better way so I can set CalculationMethod globally and never pass it and instead, having some kind of static variable(singleton) that holds the calculation method and reading it directly inside my methods without passing it. But I think there would be a problem of thread-safety then.

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;
    }
}

我无法在构造函数中传递它,因为不是属于我的域模型的东西。

I can't pass it in the constructor because it's not something that belongs to my domain model.

如何解决此类问题?有没有比我提到的两个方法更好的方法了?

How to approach this kind of problem? Is there any way better than the two I mentioned?

我在Mark Seemann的回答下的评论中问了这个问题: DDD中的应用程序级设置?

I asked this question in the comment under Mark Seemann's answer here: App-level settings in DDD?

推荐答案

正如清洁代码所述,将标志传递给方法通常被认为是子方法-最佳设计。我知道OP是另一个更为复杂的问题的替代者,但是我倾向于建议重构为多态对象模型:

As Clean Code explains, passing flags to methods is generally considered sub-optimal design. I understand that the OP is a stand-in for another, more complicated problem, but I'd be inclined to recommend to refactor to a polymorphic object model:

public interface ICalculator
{
    decimal Calculate();
}

您现在可以根据需要定义实现:

You can now define implementations as required:

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使用构造函数注入,将对象放入任何需要它的类。在您的组成根中,您可以读取配置文件或其他文件确定使用哪种实现的方法,然后仅创建该类的单个实例。这样可以赋予对象 Singleton寿命,以便在启动时完全选择计算方法,并在应用程序中的所有对象之间共享。

You can inject an ICalculator object into any class that has a need for it, using Constructor Injection. In your Composition Root, you can read a configuration file, or in some other way decide which implementation to use, and then create only a single instance of that class. This gives the object Singleton lifetime, so that the calculation method is entirely selected at startup time, and shared among all objects in the application.

这篇关于在富域模型中使用应用程序级设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆