В проекте я продолжаю работать, мы обрабатываем Медицинскую тарификацию.
Каждый раз состояние вносит изменение в официальную форму (который наши классы данных представляют), для поддержания обратной совместимости с предыдущими формами, мы добавляем новые свойства, но оставляем старые неповрежденными, и имеем свойство версии документа, которое используется для определения, какая проверка сделана и действия UI для отображения его.
Это имеет вывод к чрезмерно увеличенным в размерах классам по сроку действия проекта (почти 5 лет переданных под мандат состоянием изменений), и просто не поддержка старых форматов документов не является опцией.
Я хотел бы попытаться создать новый класс для каждой версии документа, но даже тогда у нас будет несколько копий очень похожих (хотя немного изменено) кодом. И имена классов, такие как ProgressNoteV16, ProgressNoteV17 выглядят ужасными.
Наследование не может использоваться, потому что это все еще привело бы к той же проблеме (свойства наличия классов, которые больше не необходимы). Интерфейсы сделали бы Интерфейс столь же чрезмерно увеличенным в размере, который не решит проблему.
Что решения и лучшие практики используются для решения этой проблемы?
Это довольно классическая проблема для любого агентства, которое работает с общественностью в любом качестве, особенно если это государственное или контролируемое правительством агентство. Решение нетривиально, и, вероятно, для его создания, а также последующего сопровождения потребуется значительная работа.
Это работало для меня в прошлом при решении подобных вопросов для клиентов, но, возможно, это не сработает для вас, вам нужно будет составить черновик того, что вы пытаетесь сделать, и если это имеет смысл, то сделать это.
Есть пара паттернов, с которыми стоит познакомиться (если вы еще не знакомы):
Есть две книги, которые довольно хорошо объясняют эти (и несколько других полезных):
Теперь к процессу, который я использовал в прошлом:
Надеюсь, это даст вам некоторые идеи о том, что делать.
Если наследование не может быть использовано "потому что поля в документе могут быть удалены", как вы это делаете в настоящее время?
В зависимости от деталей вашего дизайна, вы должны иметь возможность переопределить поля, неиспользуемые текущей версией документа (т.е. переопределить в подклассе для этого документа) и бросить NotSupportedException или аналогичное в реализации этого метода, если форма пытается присвоить значение. По аналогичной логике, вы можете (и, вероятно, должны) использовать интерфейсы... просто зная, что конкретная реализация может бросить исключение для свойства, которое она реализует, но которое не определено для данной версии пользовательского интерфейса.
Вы можете использовать Factory Pattern, чтобы вернуть соответствующий экземпляр объекта для данной версии формы.
Если есть некоторая общность между кодом, который слегка изменился, но в основном один и тот же, вы можете преобразовать некоторую часть этой общности в закрытый/защищенный метод, который используется несколькими публичными методами.
Что касается именования классов, то если вы используете заводскую схему, то вы можете обратиться к классу в большинстве своего кода, используя интерфейс. Только на заводе придется иметь дело с "странными" именами классов.
.Я бы реализовал это гораздо более свободным способом - класс, содержащий два поля: версию и словарь. Когда данные меняются настолько сильно, становится очень утомительно пытаться отслеживать те свойства, которые теряются и добавляются. С помощью словаря можно просто проверить, существует ли ключ.
.зависит от вашего контракта и вашего конкретного случая . Обычно лучше всего возвращать пустые коллекции , но иногда ( редко ):
null
может означать что-то более конкретное;null
. Некоторые конкретные примеры:
null
означал бы, что элемент отсутствует, .. Взгляните на эту статью: Избегайте чрезмерного разделения на подклассы с помощью шаблона дизайна декоратора
Проверка Мартином Фаулером шаблонов на вещи, которые меняются со временем, также стоит прочитать, чтобы получить полезные идеи для такого сценария дизайна
.