代码之家  ›  专栏  ›  技术社区  ›  Paul

DDD中的应用程序级别设置?

  •  14
  • Paul  · 技术社区  · 15 年前

    只是想让小组思考如何处理实体的配置细节。

    为了便于讨论,让我们以基于web的CMS或博客应用程序为例。

    给定的博客条目实体具有任意数量的实例设置,如作者、内容等。

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

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

    2) 使用一个单独的实体来保存设置,可能是一个字典,或者直接使用它,或者让它成为Entry类的成员

    你们觉得什么最容易/最灵活?我对第一个问题的担忧是,它对我来说不是非常可插拔(如果我最终想要添加更多功能),因为更改实体的类方法也会使我更改应用程序本身(这感觉像是违反OCP)。第二个感觉更重,尤其是当我不得不从字典中转换或解析值时。

    1 回复  |  直到 15 年前
        1
  •  9
  •   Mark Seemann    15 年前

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

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

    这样的类有效地保护了不变量:Name不能为null。领域模型必须像这样封装不变量,而不考虑哪个消费者将使用它们——否则,它们将无法满足灵活设计的目标。

    但您询问了默认值。如果名称有一个好的默认值,那么如何将该默认值传递给MyClass。

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

    public interface IMyClassFactory
    {
        MyClass Create();
    }
    

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

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

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