Моя проблема связана с отношениями и каскадными эффектами между свойствами, и мне интересно, каковы лучшие практики в этом отношении.
У меня есть класс, который содержит список номеров различной длины. При редактировании списка иногда пользователь предпочитает установить TargetSum, чтобы программа принудительно добавляла список к этой сумме. Я выполняю это, программно устанавливая последний элемент в списке так, чтобы list sum = TargetSum. Например, если пользователь выбирает UseTargetSum, затем устанавливает TargetSum = 10, затем создает список длиной 4 и вводит 1, 4, 2 для первых 3 элементов, тогда последний элемент программно фиксируется на 3. Пользователь не может изменить последний элемент сами.
Я делаю это негласно, обрабатывая все необходимые события, такие как изменение значения элемента списка, изменение длины списка и изменение параметра UseTargetSum. Для каждого триггера события он пересчитывает значение последнего элемента.
Работает, но при загрузке сохраненных данных произошла ошибка. Если список загружается путем последовательного добавления элементов, обработчики изменяют каждую запись. Что касается примера, когда вводится первое значение 1, обработчики говорят: «значение было только что добавлено, сумма должна быть 10, в настоящее время есть только один элемент, поэтому он должен быть 10». Таким образом, первый элемент меняется на 10 за кулисами. Когда второй элемент добавляется в следующий раз, обработчики говорят, что «значение 4 было только что добавлено, но первый элемент уже равен 10, поэтому он должен быть равен нулю». В конце загрузки окончательный список читается как 10,0, 0,0 вместо 1,4,2,3.
Я знаю, что можно изменить порядок загрузки так, чтобы я получил правильный список. Например, я мог бы избежать включения обработчиков событий TargetSum до тех пор, пока не будут загружены все данные. Список сначала будет создан как 1,4,2,3, а затем обработчики ничего не изменят.
Но этот опыт заставляет меня задаться вопросом, открываю ли я дверь для других подлых побочных эффектов. Кажется, вы должны иметь возможность загружать данные, не слишком заботясь о неявном порядке. Также кажется необычным иметь «каскадные» эффекты между свойствами класса. Есть ли более приемлемый подход?
Другой альтернативой, которую я рассматриваю, является принудительное использование TargetSum только внутри форм пользовательского интерфейса. То есть, когда вы знаете, что это пользователь вносит изменения, тогда применяйте TargetSum, но в противном случае оставьте логику базового класса в покое. Таким образом, загрузка базы данных и т. Д. Остаются без изменений. Но я полагаю, что недостатком отсутствия повсеместного правоприменения является то, что он открывает дверь неправильных сумм через непредвиденные осложнения.