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