Настройки уровня приложения в DDD?

Просто хотел, чтобы группы думали о том, как обрабатывать детали конфигурации объектов.

То, о чем я сейчас думаю, это настройки высокого уровня, которые могут быть изменены администратором. то, что вы можете сохранить в приложении или web.config в конечном счете, но с точки зрения DDD должно быть установлено где-то в объектах явно.

Для аргументации возьмите в качестве примера веб-приложение CMS или блог.

У данного объекта записи блога есть любое количество настроек экземпляра, таких как Author, Content и т.д.

Но вы также можете установить (например) значение по умолчанию Описание или ключевые слова, которые должны начинаться с всех записей на сайте, если они не будут изменены автором. Конечно, вы можете просто создать эти константы в классе, но тогда владелец сайта не смог изменить настройки по умолчанию.

Итак, мои мысли таковы:

1) используйте свойства класса (статические) для представления этих параметров, а затем задайте их, когда приложение запустится, либо установив их из БД, либо из web.config.

или

2) используйте отдельный объект для хранения настроек, возможно, словарь, либо используйте его напрямую, либо являетесь членом класса Entry

Что поражает всех вас как самого легкого/гибкого? Мои проблемы в первую очередь состоят в том, что это не делает меня очень привлекательным (если я хочу добавить дополнительные функции), так как изменение методов класса сущности заставило бы меня также изменить само приложение (что кажется нарушением OCP). Второй чувствует себя более тяжелым, тем не менее, особенно если мне тогда придется выставлять или анализировать значения из словаря.

Ответы

Ответ 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 для его создания вместо того, чтобы его вручную обновлять.