我想说,从领域模型的角度来看,一个值是否可配置并不重要——重要的是它是外部定义的。
假设您有一个必须有名称的类。如果始终需要名称,则无论值的来源如何,都必须将其封装为不变量。这是一个 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;
}
}
}
像这样的类有效地保护了不变量:名称不能为空。领域模型必须封装这样的不变量,而不考虑哪个消费者将使用它们 - 否则,它们将无法满足柔软设计的目标。
但您询问了默认值。如果您有一个很好的 Name 默认值,那么如何将该默认值传达给 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 来创建它,而不是手动新建它。