Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Which Design Pattern to use for versioning???

665 views
Skip to first unread message

cart...@gmail.com

unread,
Jan 19, 2006, 8:35:00 AM1/19/06
to
I am still a bit new to Design Patterns. I need to implement a
history/revision system. Such that there will be an object and as it's
values change, the revision changes and there is a history of the old
values. What is the correct design pattern to use to implement
something like this?

H. S. Lahman

unread,
Jan 19, 2006, 5:33:59 PM1/19/06
to
Responding to Cartoper...

Maybe a design pattern will show up somewhere, but I think you have some
basic OOA/D to do first. For instance, clearly there is some notion of
Current vs. Previous. But of what? Also, how do you plan to handle
identity?

If all that changes are the values of an object (i.e., properties can't
be added or removed), then probably the simplest approach is to think of
a "versionable object" whose identity is compound, such as {object ID,
time stamp} where 'object ID' is the identity of the underlying entity
whose versions are being kept track of. Now all you have to do is order
the collection by time stamp.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
h...@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
(888)OOA-PATH

bruno at modulix

unread,
Jan 20, 2006, 8:20:30 AM1/20/06
to
You may want to look at proxy and memento.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'on...@xiludom.gro'.split('@')])"

richard_j...@hotmail.com

unread,
Jan 23, 2006, 7:07:09 AM1/23/06
to
If you're going to want to undo and redo to previous versions, you
could also look at the command pattern to encapsulate the changes made.

If you create "Unexecute" and "Execute" operations", you will be able
to go back and forwards between different versions easily. You might
be able to also add a "DisplayChanges" method to your command to list
the changes made between different versions.

Richard

Web site: http://www.richardjonas.com
Blog: http://www.richardjonas.com/blog

herc

unread,
Jan 23, 2006, 6:42:09 PM1/23/06
to
To answer H. S. Lahman question of what needs to be version, it is a
hierarchy of objects that need fixed properties to be versioned. There
is a schedule object. The schedule object has one or more lines, where
the count of lines can change. The line objects have a fixed set of
properties that can change value.

The objective is to be able to track changes to schedules so that it is
possible to determine which lines changed. Further more it be easy to
determine which properties within said line changed.

At this early stage in the development it has not been determined how
many objects like this will need to maintain version. So I am looking
for a solution that will make it easy to add versioning to an object if
the object needs it and easy to remove it, if it is not needed.

I looked into both the proxy and memento design patterns. Is the best
approach to make a proxy for each versioned object that has a caretaker
object for the versioned data? Does anyone know where I might find an
example of something like this?

cartoper

H. S. Lahman

unread,
Jan 24, 2006, 12:47:18 PM1/24/06
to
Responding to Herc...

> To answer H. S. Lahman question of what needs to be version, it is a
> hierarchy of objects that need fixed properties to be versioned. There
> is a schedule object. The schedule object has one or more lines, where
> the count of lines can change. The line objects have a fixed set of
> properties that can change value.

OK, so far we have...

1 contains *
[Schedule] --------------- [Line]
+ lineCount R1 + element1
+ element2
...

where the number and types of data elements in [Line] is fixed. (I've
made lineCount a property of [Schedule] to highlight it but I would
normally expect it to be a responsibility of the collection class that
implements the R1 relationship.)

> The objective is to be able to track changes to schedules so that it is
> possible to determine which lines changed. Further more it be easy to
> determine which properties within said line changed.

Do you need to keep track of just the fact that it changed from some
prior version or do you need to know the prior change? If the latter,
do you need to keep track of just the last or all prior changes in some
order?

I am pushing back with these questions because the basic design will
very likely change depending on the answers. That why I originally
suggested that there was some basic design work to be done before
worrying about applying patterns.

>
> At this early stage in the development it has not been determined how
> many objects like this will need to maintain version. So I am looking
> for a solution that will make it easy to add versioning to an object if
> the object needs it and easy to remove it, if it is not needed.

So there a concept of [Version] that may collect multiple [Line]
changes(?) If so, that suggests something like:

[Schedule]
| 1
|
| R1 <<ordered>>
|
| captured in
| *
[Version]
+ versionID
+ lineCount
| *
|
| R2
|
| consists of
| 0..*
[Line]
+ lineID
+ versionID
+ element1
+ element2
...

Here we have my original suggestion of a compound identity {LineID,
versionID} for the [Line] objects.

The second sentence introduces a completely new requirement that makes
versioning optional. However, the above model still works since no
versioning can be accommodated by just having a single [Version]
instantiated. One can also get more exotic:

1 R3
[Schedule] ----------------------------+
+ currentLineCount |
| 1 |
| |
| R1 <<ordered>> |
| | currently
| captured in | consists of
| 0..* | *
[Version] [Line]
+ versionID + lineID
+ versionLineCount + element1
| * + element2
| ...
| R2 | 1
| |
| consists of |
| * 0..1 derived from | R4
[PriorLine] --------------------------+
+ lineID
+ versionID
+ element1
+ element2
...

Now we can deal with no versioning by not instantiating the R1
relationship. I think this will work for all the requirements you have
stated so far without the need for any GoF patterns.

[If you don't care about actual prior values, things can be a lot
simpler. I'll leave it as an exercise to figure out how to modify this
model for keeping track of revisions incrementally, like most version
control systems do. B-)]

> I looked into both the proxy and memento design patterns. Is the best
> approach to make a proxy for each versioned object that has a caretaker
> object for the versioned data? Does anyone know where I might find an
> example of something like this?

You need to develop a preliminary design (objects, relationships, and
responsibilities) that resolves all the requirements before worrying
about patterns. Don't use patterns to drive the design; use patterns to
resolve issues that come up in the design.

The GoF patterns almost all address a single general problem: one has a
relationship between two objects that is so dynamically complex that one
cannot express it with a simple static association relationship (as
above). The GoF patterns then resolve different flavors of that problem
with delegation, subclassing, and polymorphic substitution in one form
or another. So before you look for patterns you have to have a
relationship in your initial design that presents a problem.

0 new messages