What versioning design pattern would you recommend

I have a requirement to build ‘versioning’ into an application and was wondering how best to approach it.

I have this general pattern:

Model A has many B’s

Where on update the attributes of A need to be versioned and its associated objects (B’s) also need to be versioned. So the application will display the current version of A, but it must also be possible to view previous versions of A and its associated objects.

I would like to use a document store however this is only a portion of the application and having a doc store and a relation database would introduce more complexity.

I have considered using a star schema, but before I progress I was wondering if there is a design pattern floating around tackling this problem?

This question is slanted towards resolving the issue of storing the versions of an associated object in a relational database. Where there is an inherent need to be able to effectively query the data (ie serializing object won’t suffice).

Update: What I was thinking/have implemented but want to see if the is “a better way”

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

Where I would be duplicating model A and all the associated B’s and incrementing the version attribute. Then doing a select to join the B’s via b_version and b.version. Just wondering if this can be done better.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Martin Fowler has some good articles on time/versioning-based design patterns – definitely worth a look:

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

Method 2

I don’t think there is no specific GoF design pattern per se for versioning because there exists many implementations of it.

The most simple implementation of versioning is a linked list of objects. Where each node in the list is a new revision of whatever the versionable object is. To save space you also implement some kind of a diff that shows what the difference is between the revisions. That way you can store diffs in the database, but also the final version of the versionable object since the version control system should be able to derive the versions in between.

The database schema could principally look something like this (you can see this pattern in most wiki systems):

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

If you want to go hardcore with branching and stuff you might want to consider have a look at DAG which is what modern distributed version control systems use.

Now if we talk about your example a whole slew of objects that needs to be saved in configurations. I.e. we have to pick out the revisions of objects that we want for the model. It means we have a many to many relationship (which is solved with an intermediary table), sort of like this:

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

I hope this helps.

Method 3

I’ve solved this problem in rails by using the acts_as_versioned plugin. When you apply it to a model, it assumes there is a model_name_version in addition to the model_name table. Every time a model is saved, the old version along with a timestamp is copied into the model_name_version table.

This approach keeps the size of the model table manageable while still allowing search on previous versions. I’m not sure the plugin handles the chaining you want out of the box, but it wouldn’t be hard to add.

Method 4

A combination of the Memento pattern with the Observer pattern should fit your needs. Also have a look at the Visitor pattern for possible application in your case…

Method 5

What about saving a XML snapshot of the database shema you want to version? And then be able to change the state of the database?


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x