DDD中的应用程序级别设置? [英] App-level settings in DDD?

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

问题描述

只想让小组成员思考如何处理实体的配置详细信息。



我特别想的是高级设置,该设置可能是管理员-改变了。最终可以存储在应用程序或web.config中的那种东西,但是从DDD角度来看,应该在对象中的某个位置显式设置。



,我们以基于Web的CMS或博客应用为例。



给定的Blog Entry实体具有任意数量的实例设置,例如Author,Content等。

p>

但是,您可能还想设置(例如)默认的描述或关键字,如果作者没有更改,则应以网站中的所有条目开头。当然,您可以只在类中创建这些常量,但是站点所有者无法更改默认值。



所以我的想法如下:



1)使用类级(静态)属性表示这些设置,然后在应用程序启动时进行设置,可以从数据库或从web.config进行设置。 / p>



2)使用单独的实体保存设置,可能是字典,可以直接使用它,也可以使用它是Entry类的成员吗?



最容易/最灵活的方式是什么让您印象深刻?关于第一个问题,我担心的是它不会给我带来太大的可插拔性(如果我最终想添加更多功能),因为更改实体的类方法也会使我也更改应用程序本身(感觉就像违反了OCP一样) )。不过,第二个感觉更沉重,特别是如果我然后必须将值转换或解析为字典之外的话。

解决方案

我要说的是,从域模型的角度来看,值是否可配置无关紧要-重要的是它是在外部定义的。



假设您拥有必须具有名称的类。如果始终需要名称,则必须将其封装为不变形式,而与值的来源无关。这是一个C#示例:

 公共类MyClass 
{
私有字符串名称;

public MyClass(s​​tring name)
{
if(name == null)
{
throw new ArgumentNullException( name);
}

this.name =名称;
}

公共字符串名称
{
get {return this.name; }
set
{
if(value == null)
{
throw new ArgumentNullException( name);
}
this.name = value;
}
}
}

像这样的类可以有效地保护不变式:名称不能为null。域模型必须封装这样的不变量,而不必考虑哪个消费者将使用它们-否则,它们将无法达到Supple Design的目标。



但是您询问默认值价值观。如果名称的默认值很好,那么如何将该默认值传递给MyClass。



这是工厂派上用场的地方。您只需将对象的构造与其实现分开。无论如何,这通常是一个好主意。选择您选择Abstract Factory还是Builder实现并不那么重要,但是Abstract Factory是一个很好的默认选择。



对于MyClass,我们可以定义IMyClassFactory接口:

 公共接口IMyClassFactory 
{
MyClass Create();
}

现在,您可以定义从配置文件中提取名称的实现:

  public ConfigurationBasedMyClassFactory:IMyClassFactory 
{
public MyClass Create()
{
var name = ConfigurationManager.AppSettings [ MyName];
返回新的MyClass(name);
}
}

请确保需要MyClass实例的代码使用IMyClassFactory来创建它,而不是手动创建它。


Just wanted to get the groups thoughts on how to handle configuration details of entities.

What I'm thinking of specifically is high level settings which might be admin-changed. the sort of thing that you might store in the app or web.config ultimately, but from teh DDD perspective should be set somewhere in the objects explicitly.

For sake of argument, let's take as an example a web-based CMS or blog app.

A given blog Entry entity has any number of instance settings like Author, Content, etc.

But you also might want to set (for example) default Description or Keywords that all entries in the site should start with if they're not changed by the author. Sure, you could just make those constants in the class, but then the site owner couldn't change the defaults.

So my thoughts are as follows:

1) use class-level (static) properties to represent those settings, and then set them when the app starts up, either setting them from the DB or from the web.config.

or

2) use a separate entity for holding the settings, possibly a dictionary, either use it directly or have it be a member of the Entry class

What strikes you all as the most easy / flexible? My concerns abou the first one is that it doesn't strike me as very pluggable (if I end up wanting to add more features) as changing an entity's class methods would make me change the app itself as well (which feels like an OCP violation). The second one feels like it's more heavy, though, especially if I then have to cast or parse values out of a dictionary.

解决方案

I would say that that whether a value is configurable or not is irrelevant from the Domain Model's perspective - what matters is that is is externally defined.

Let's say that you have a class that must have a Name. If the Name is always required, it must be encapsulated as an invariant irrespective of the source of the value. Here's a C# example:

public class MyClass
{
    private string name;

    public MyClass(string name)
    {
        if(name == null)
        {
            throw new ArgumentNullException("name");
        }

        this.name = name;
    }

    public string Name
    {
        get { return this.name; }
        set
        {
            if(value == null)
            {
                throw new ArgumentNullException("name");
            }
            this.name = value;
        }
    }
}

A class like this effectively protects the invariant: Name must not be null. Domain Models must encapsulate invariants like this without any regard to which consumer will be using them - otherwise, they would not meet the goal of Supple Design.

But you asked about default values. If you have a good default value for Name, then how do you communicate that default value to MyClass.

This is where Factories come in handy. You simply separate the construction of your objects from their implementation. This is often a good idea in any case. Whether you choose an Abstract Factory or Builder implementation is less important, but Abstract Factory is a good default choice.

In the case of MyClass, we could define the IMyClassFactory interface:

public interface IMyClassFactory
{
    MyClass Create();
}

Now you can define an implementation that pulls the name from a config file:

public ConfigurationBasedMyClassFactory : IMyClassFactory
{
    public MyClass Create()
    {
        var name = ConfigurationManager.AppSettings["MyName"];
        return new MyClass(name);
    }
}

Make sure that code that needs instances of MyClass use IMyClassFactory to create it instead of new'ing it up manually.

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

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