Reputation: 8019
We develop a desktop application which goes into versions. We save the data in a file (which has version in which it is saved) and open it lateron to work on it. Since our data model keeps changing over versions, we keep adding APIs like upgrade_from_ver1_to_ver2. This is getting chiotic, since we are now in version 10.0. We also slowly stop supporting older versions (say files saved before 4.0). Can you suggest a better way or a design pattern to save and provide backward compatibility?
It will be good if this can be designed as a seperate utility, called during import/opening of data files. It shall also be called seperately just to get current data model from old data files.
Upvotes: 3
Views: 1662
Reputation: 49
You can use ParallelChange Design Pattern here.
To give you a little bit idea, this pattern has 3 phases expand, migrate, and contract.
Let say you have method1
in your file and you want to update the method structure.
public void method1(Obj1 obj1) { ... }
1. Expand
Now you need to support different data structure with backward compatibility. Then add new method keeping the old one as is.
public void method1(Obj1 obj1) { ... } public void method1(Obj2 obj2) { ... }
After this release, all your clients will still use the method1(Obj1 obj1)
. You have just added capability to call a different method which will use now onwards.
2. Migrate
In this phase, you need to upgrade your all clients to new method structure ie method1(Obj2 obj2)
. Sometimes we need to force the client to use the new method structure and sometimes the client moves gradually. We generally stop to give new features to deprecated methods. Like after the first Expand, we found a bug in method1(Obj1 obj1)
, we say this will be solved in method1(Obj2 obj2)
.
3. Contract
Once your all clients are moved, it's totally safe to remove your method1(Obj1 obj1)
implementation.
Eventually, you will upgrade your system from version to version with backward compatibility.
The only downfall that I personally feel is, it will take at least 3 release before you remove your whole code. But without a doubt, this would be surely hassle-free.
Upvotes: 0
Reputation: 556
How about you just implement an upgrade function from the version before to the new version? Then you can chain those together to upgrade from an older version.
This seems to me the minimal implementation effort, while always allowing to upgrades from any prior version. The downside is, that you might loose information in the conversion chain, e.g. if the possible values of one property is reduced in one version and later extended again.
Upvotes: 4
Reputation: 11442
The first important thing to do is to have a separate class(es) for saving your data so your data objects aren't burdened with the responsibility of saving.
Next I would use the template pattern, defining the basics of your read/open operation. Your AbstractReader
class might just define a single Read
method. You could then create classes inheriting from the AbstractReader
- potentially one for each file version. You could then use the abstract factory pattern to detect the version of file being opened, then return the corresponding Reader
implementation for that version.
Upvotes: 0