Короткий ответ - нет, не существует элегантного или удобного способа применения порядка построения класса, который должным образом не реализует «Свободный интерфейс», как вы связались.
Более длинный ответ начинается с игрыАдвокат дьявола.Если бы у меня были зависимые свойства (то есть свойства, которые требовали, чтобы вначале были установлены другие свойства), я мог бы реализовать их примерно так:
method SetLength(int millimeters)
if color is null throw new ValidationException
length = millimeters
return this
end
(ПРИМЕЧАНИЕ: приведенное выше не отображается ни на один реальный язык,это просто psuedocode)
Так что теперь у меня есть исключения для беспокойства.Если я не подчиняюсь правилам, беглый объект выдаст исключение.Теперь предположим, что у меня есть объявление, подобное вашему:
var config = new Fluent().SetLength(2).SetHeight(1).SetDepth(3).SetColor("blue");
Когда я ловлю ValidationException
, потому что длина зависит от того, какой цвет задается первым, как я, как пользователь, должен знать, каков правильный порядок?Даже если бы каждый метод SetX
находился на отдельной строке, трассировка стека просто выдаст мне строку, где переменная config
была объявлена в большинстве языков.Кроме того, как я должен держать правила этого объекта прямо в моей голове по сравнению с другими объектами?Это кокофония противоречивых идеалов.
Такие проверки приоритетов нарушают дух подхода «Свободного интерфейса».Этот подход был разработан для удобной настройки сложных объектов.Вы получаете удобство, когда пытаетесь навести порядок.
Чтобы правильно и элегантно реализовать свободный интерфейс, есть пара рекомендаций, которые лучше всего соблюдать, чтобы поблагодарить потребителей вашего класса:
- Предоставление значимых значений по умолчанию: сводит к минимуму необходимость изменения значений и сводит к минимуму шансы на создание недопустимого объекта.
- Не выполняйте проверку конфигурации до тех пор, пока об этом явно не попросят.Это может происходить, когда мы используем конфигурацию для создания нового полностью сконфигурированного объекта или когда потребитель явно вызывает метод
Validate()
. - В любых выданных исключениях, убедитесь, что сообщение об ошибке ясно и указывает налюбые несоответствия.