Какой шаблон дизайна версий вы бы порекомендовали - PullRequest
20 голосов
/ 17 февраля 2009

У меня есть требование встроить «управление версиями» в приложение, и мне было интересно, как лучше к нему подойти.

У меня есть такая общая схема:

Модель A имеет много B

Где при обновлении атрибуты A должны быть версионными, а связанные с ним объекты (B) также должны быть версионными. Таким образом, приложение будет отображать текущую версию A, но также должна быть возможность просмотра предыдущих версий A и связанных с ней объектов.

Я хотел бы использовать хранилище документов, однако это только часть приложения, и наличие хранилища документов и базы данных отношений представило бы большую сложность.

Я рассмотрел вопрос об использовании схемы типа «звезда», но перед тем, как продолжить, мне стало интересно, существует ли шаблон проектирования, решающий эту проблему?

Этот вопрос направлен на решение проблемы сохранения версий связанного объекта в реляционной базе данных. Там, где есть неотъемлемая необходимость иметь возможность эффективно запрашивать данные (т.е. сериализации объекта будет недостаточно).

Обновление: то, что я думал / реализовал, но хочу посмотреть, является ли это "лучшим способом"

,---------. 1      * ,--------.
| Model A |----------| Model B|
`---------'          `--------'
|PK       |          | a_id   |
|b_version|          |version |
|version  |          `--------'
`---------'

Где я буду дублировать модель A и все связанные с ней B и увеличивать атрибут версии. Затем сделать выбор, чтобы присоединиться к B через b_version и b.version. Просто интересно, можно ли это сделать лучше.

Ответы [ 5 ]

10 голосов
/ 18 февраля 2009

У Мартина Фаулера есть несколько хороших статей о шаблонах проектирования, основанных на времени / управлении версиями - определенно стоит посмотреть:

http://martinfowler.com/eaaDev/timeNarrative.html

7 голосов
/ 17 февраля 2009

Я не думаю, что не существует определенного шаблона проектирования GoF как такового для управления версиями, потому что существует много его реализаций.

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

Схема базы данных может выглядеть примерно так (вы можете увидеть этот шаблон в большинстве вики-систем):

+--------------------+ 1     * +-----------------------------+
| VersionableObject  |---------| Diff                        |
+--------------------+         +-----------------------------+
| lastStateContent   |         | difference                  |
| originalAuthor     |         | revision                    |
| #dates and whatnot |         | # userId, dates and whatnot |      
+--------------------+         +-----------------------------+

Если вы хотите заняться хардкором с ветвлением и тому подобным, подумайте о DAG , который используют современные распределенные системы контроля версий.

Теперь, если мы поговорим о вашем примере, целый ряд объектов, которые необходимо сохранить в конфигурациях. То есть мы должны выбрать ревизии объектов, которые мы хотим для модели. Это означает, что у нас есть отношение многие ко многим (что решается с помощью промежуточной таблицы), примерно так:

+---+ 1   * +---------------+ 1   * +-----------------+ *   1 +-------+
| B |-------| Diff          |-------| ModelSelection  |-------| Model |
+---+       +---------------+       +-----------------+       +-------+
            | revisionNo    |       | {PK} configId   |
            | {FK} configId |       | {FK} modelId    |
            +---------------+       +-----------------+

Надеюсь, это поможет.

2 голосов
/ 18 февраля 2009

Я решил эту проблему в рельсах с помощью плагина acts_as_versioned. Когда вы применяете его к модели, предполагается, что есть model_name_version в дополнение к таблице model_name. Каждый раз, когда модель сохраняется, старая версия вместе с отметкой времени копируется в таблицу model_name_version.

Этот подход позволяет управлять размером таблицы модели, сохраняя при этом поиск в предыдущих версиях. Я не уверен, что плагин обрабатывает цепочки, которые вы хотите из коробки, но добавить его будет несложно.

1 голос
/ 17 февраля 2009

Сочетание шаблона Memento с шаблоном Observer должно соответствовать вашим потребностям. Также взгляните на шаблон Visitor для возможного применения в вашем случае ...

0 голосов
/ 27 октября 2010

А как насчет сохранения снимка XML базы данных shema, которую вы хотите версии? И тогда сможет ли изменить состояние базы данных?

...