Page 1 of 1

Maintaining variants of an application

Posted: Thu Nov 11, 2010 8:45 pm
by gidireich
We have a product which is being slightly customized for each client. The exact customization is unpredictable - we assume that any point in the code can become needing change. However, we want to keep one code base, as 90+% of the code will be identical, so we don't have to merge every update or new feature to each client separately.

How can this be done?

The project is written in PHP with the Yii framework.

Basically, we would like something like this: Every client will have a folder with a 'mirror' of the code. That 'mirror' will include only those classes customized for the client. Than, at runtime, the clients identity will be known, and every mention of classes name will be resolved to the generic version of the class - if no client specific version exists for this client, or to the client customized version of that class - if such a version does exist.

I'll appreciate comments about the general design question.
Any comments on the above solution.
Are there other ways to achieve what I want to achieve?
Maybe some code generation tool for generating the client specific version from the current main code?

And also there is the implementation question. How can this be implemented in PHP and Yii?

I thought first to use PHPs __autoload. However, it will anyway choose only one version of the class. And this is a problem, because we'll need to choose the client specific version every time except of one: when defining the client specific version of the class, we will extend the general purpose version of that class. So classes version can not be resolved at the loading time, both need to be loaded, and the client specific will be used every time except of one.

Thank you

Re: Maintaining variants of an application

Posted: Sun Nov 14, 2010 11:08 am
by josh
This is object oriented programming. There is inheritance based re-use, where you try and make everything instantiate the "client's" class instead of your "core" class. There is also component based re-use where your core classes hold instances of "strategy" objects. These strategy objects just get replaced with client specific strategies. The latter is more flexible because you do not need to modify the rest of your system to instantiate the new class, you may also mix & match strategies (kind of like multiple inheritance which isn't possible)

Example, you have a 'search'. This 'search' has a 'search strategy'. The default strategy is to search thru a directory of files calling strpos() until the query is found. Now lets say Google hired you and this next app needs to call their search appliance instead of your inferior strategy, you simply write a new strategy that calls their search appliance. The rest of your application is still using the same exact 'search' class that works exactly the same from a black box point of view, however that search is holding an instance of a 'google strategy' now.

At first glance it looks redundant because it seems like you have two search classes now, if anyone tells you its redundant you can tell them they're wrong because one is the search, the other is the search strategy. Search strategies' responsibility is to find matching documents & scores. The 'search' object's responsibility is different, to process a text query and pass it to a strategy, and process the results.