Ответ 1
Я бы сказал, что независимо от того, является ли значение настраиваемым или нет, оно не имеет отношения к перспективе модели домена - важно то, что это внешне определено.
Скажем, что у вас есть класс, который должен иметь имя. Если имя всегда требуется, оно должно быть инкапсулировано как инвариант независимо от источника значения. Здесь пример С#:
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;
}
}
}
Подобный класс эффективно защищает инвариант: имя не должно быть нулевым. Модели доменов должны инкапсулировать такие инварианты без какого-либо отношения к тому, какой потребитель будет их использовать, иначе они не соответствовали бы цели Supple Design.
Но вы спрашивали о значениях по умолчанию. Если у вас есть хорошее значение по умолчанию для Name, то как вы связываете это значение по умолчанию с MyClass.
Это то, где Фабрики пригождаются. Вы просто отделяете построение своих объектов от их реализации. В любом случае это очень хорошая идея. Если вы выбрали абстрактную реализацию Factory или Builder, это менее важно, но абстрактный Factory является хорошим выбором по умолчанию.
В случае MyClass мы можем определить интерфейс IMyClassFactory:
public interface IMyClassFactory
{
MyClass Create();
}
Теперь вы можете определить реализацию, которая вытаскивает имя из файла конфигурации:
public ConfigurationBasedMyClassFactory : IMyClassFactory
{
public MyClass Create()
{
var name = ConfigurationManager.AppSettings["MyName"];
return new MyClass(name);
}
}
Убедитесь, что код, который требует экземпляров MyClass, использует IMyClassFactory для его создания вместо того, чтобы его вручную обновлять.