4

For this question, I'll give an example module to facilitate the discussion, Let's say the module is a calculation engine, It currently servers its purpose for its current audience. The requirement is to clone the same engine but with some tweaking for an entirely new audience. Given that, these are Considerations/Factors that will affect the design solution:

  1. User expects that the current engine will remain unchanged, because its not part of the requirement (note the new engine is for some new audience, and does not affect the users of the current engine).
  2. In addition to #1, the expectation is no regression testing for the code base of the current engine since no changes are introduced.
  3. Just to drive the point, refactoring the current engine to make it flexible to address both current and new engines, will not be an option given that will not satisfy the 2 points above.
  4. We can expect in the future that there will be exclusive changes for each engine, ie. change is applicable only to the new engine hence should not affect the current.
  5. Tight deadline.

However, I am still conflicted, since:

  1. It will inherently be a copy-paste solution.
  2. Duplicate code.
  3. Maintenance issue for code changes that should be common to both.
  4. Does not address extension issue, ie. a third engine, and so forth could all be possible.

Is the compromise acceptable in this situation, given the user expectations highlighted above? And followup question, is there something I can add to the solution that will address the conflicting issues but at the same time satisfy the user requirements?

Martijn Verburg
  • 22,006
  • 1
  • 49
  • 81
  • I'm not trying to play semantics here, but aren't you really talking about 'extending' a module rather than 'cloning' one? – Jim G. Apr 26 '12 at 02:01
  • Unfortunately, I'm referring to cloning, because that would mean copy-pasting in order to decouple the new engine from the current engine. Decouple, because we do not want the current engine to be affected by any changes related to this new engine – Carlos Jaime C. De Leon Apr 26 '12 at 02:04
  • 1
    Did you compile that "engine" to a DLL or library? If not, I highly encourage you to do so. After you do so, you can give yourself the potential to extend rather than "clone" the engine. – Jim G. Apr 26 '12 at 02:07
  • Both will reside in the same application release and CVS project unfortunately. Thanks for the suggestion though, it did not cross my mind, however its not applicable in our case sadly. – Carlos Jaime C. De Leon Apr 26 '12 at 02:30
  • What kind of "tweaking" are you referring to? API-breaking, result-breaking, refactoring, performance-related or what? – rjnilsson Apr 26 '12 at 13:39

3 Answers3

4

It sounds to me like you want to be considering branching your code, which is basically going to clone your code-base for development and support of your two projects, while allowing you the flexibility to merge changes as needed. Thus you end up with a new branch in your version control system, and you decide whether to continue support for the original version in the branch or the mainline.

If you are considering phasing out your initial version, then you may wish to throw support into a branch, and have your second version continue on the mainline. In both cases however, maintenance could result in a change that is useful in both old and new version, so you would want to manage your branching/merging such that you could take advantages of changes without needing to edit two individual projects.

I have perhaps oversimplified my answer here, however it is really to point out that you will run into serious management overheads and scheduling bottlenecks if you choose to maintain two separate products when you could have otherwise shared much of the code base between the two products.

The other alternative might be to break the product down into smaller modules. A common base layer where all of the unchanged common code can reside, and a pair of unique and dependant products as a higher layer to the base. This too can have it's problems, yet can be a relatively simple thing to manage if supported with a good automated build/release process.

S.Robins
  • 11,385
  • 2
  • 36
  • 52
1

This sounds like one of those business issues that sometimes you just have to deal with and accommodate. For example, we have customers in the pharmaceutical industry and once they validate a version of our software for their production line, they can't change versions without a significant amount of paperwork and re-validation. We maintain custom branches of our code base for these customers where we "guarantee" (as a matter of policy) that the only changes present are bug fixes that have been deemed relevant to their process and are provided only at their request.

Dave Nay
  • 3,809
  • 2
  • 18
  • 25
1

Given those constraints, then I think the best option is to fork the code into two branches. One normally does this in the version control system, not a simple file system copy. When you branch in the version control system, common history is perserved, and integrating bug fixes from the new branch to the legacy branch can be performed at best automatically and at worst manually with machine assistance. I would not put this in the category of copy-paste programming, which I generally look down upon.

This development pattern is actually quite common. When you make a major release of some software, call it version 1.0, you basically want to keep it unchanged as you charge off and begin version 2.0. Around the time of release, you create a branch off the main trunk called 1.0 (or just a tag/label) to clearly mark what got shipped. As you work on 2.0, or as people use your software, bugs are encountered and fixes are found.

Now you really want to apply those fixes on both the 1.0 branch and the main trunk, so you do so. There are several approaches to this. One is to simply apply the same edits to the same files on both the 1.0 and main branches. This can be the easiest but is a little error prone.

Another is to apply the fix on one branch and then integrate the changed files from one branch to the other. In large projects this can often be done automatically, as the files on both branches may not have changed since release and are identical. The version control system knows the history of both branches, so applying the fixes on 1.0 and integrating from 1.0 to main is probably the better choice, as the version control system will generally not be confused by new development made on the post-1.0 files and can apply the fixes automatically. Going the other way around is not recommended because the version conrol system can't tell the differences between changes on the post-1.0 file that are new development and those that are bug fixes. This could lead to inappropriate code being introduced to the 1.0 branch.

Sometimes, the post-1.0 files on the main branch are so different from what shipped as to make automatic integration impossible. In this case, either the fix does not need to be applied in the new code, or you simply must be careful and apply it manually in both. Whatever path you choose, always carefully look over your changes before checking them in.

Randall Cook
  • 2,470
  • 19
  • 19