Pau*_*aul 14 domain-driven-design
只是想让小组了解如何处理实体的配置细节.
我正在考虑的是高级别设置,可能是管理员更改的.你可能最终存储在应用程序或web.config中的那种东西,但是从DDD角度来看应该明确地设置在对象的某个地方.
为了论证,我们以一个基于Web的CMS或博客应用为例.
给定的博客条目实体具有任意数量的实例设置,如作者,内容等.
但是,您也可能希望设置(例如)默认描述或关键字,如果作者没有更改网站中的所有条目,则应该从这些条目开始.当然,你可以在课堂上制作这些常量,但网站所有者无法更改默认值.
所以我的想法如下:
1)使用类级别(静态)属性来表示这些设置,然后在应用程序启动时设置它们,从数据库或web.config设置它们.
要么
2)使用单独的实体来保存设置,可能是字典,要么直接使用它,要么让它成为Entry类的成员
最容易/最灵活的是什么让你大家都感到震惊?我对第一个问题的关注是,它不会让我觉得非常可插拔(如果我最终想要添加更多功能),因为更改实体的类方法会让我改变应用程序本身(这感觉就像是OCP违规).然而,第二个感觉它更重,特别是如果我必须从字典中转换或解析值.
我想说一个值是否可配置与域模型的观点无关 - 重要的是外部定义.
假设你有一个必须有名字的班级.如果始终需要Name,则必须将其封装为不变量,而不管值的来源如何.这是一个C#示例:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
像这样的类有效地保护了不变量:名称不能为空.域模型必须封装这样的不变量,而不考虑哪个消费者将使用它们 - 否则,它们将无法满足Supple Design的目标.
但是您询问了默认值.如果Name具有良好的默认值,那么如何将该默认值传递给MyClass.
这就是工厂派上用场的地方.您只需将对象的构造与其实现分开即可.无论如何,这通常是一个好主意.无论您选择抽象工厂还是构建器实现都不太重要,但抽象工厂是一个很好的默认选择.
在MyClass的情况下,我们可以定义IMyClassFactory接口:
public interface IMyClassFactory
{
MyClass Create();
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以定义从配置文件中提取名称的实现:
public ConfigurationBasedMyClassFactory : IMyClassFactory
{
public MyClass Create()
{
var name = ConfigurationManager.AppSettings["MyName"];
return new MyClass(name);
}
}
Run Code Online (Sandbox Code Playgroud)
确保需要MyClass实例的代码使用IMyClassFactory创建它而不是手动新建它.