We are in the process of modernizing an existing legacy application and as part of that we are replacing a proprietary off-the-shelf product that is deeply integrated with the application - with a new off-the-shelf product.

There are two approaches we are looking for co-existence.

  1. Update the Original application (say App1) to work with both off-the-shelf vendor products (calling them VP1 and VP2). This would mean modifying the existing codebase and updating all integration points so that they work for both vendor products. We are planning on achieving this via an application level switch - so depending on a condition the process flow will use implementation for VP1 or VP2 to process requests. This would mean a single application which has both implementations (abstracted via interfaces) can be used to process requests.

  2. Second option is to have two systems running in parallel during the co-existence period. The way this is being proposed is to create a copy of existing application (App1), remove all implementations for the existing vendor product VP1 and re-implement them with the new vendor product VP2. This new copy of the application will then be hosted as a separate instance (lets call it NewApp1) - and the users will have to switch between the Original (App1 and NewApp1) to perform business functions during co-existence. This is with a view to leave the existing application as-is and not breaking the current functionality. It is also to minimize effort involved in re-testing the entire application (App1) if it is modified.

Which of the two approaches is more suitable in case of an application that essentially is replacing the underlying vendor product?

Edit (30/01)

Adding a little more context and rationale in support of Option #1 (at-least for the use-case that i am dealing with). This is over and beyond what has already been added in the comments below.

  1. It is important to note that the application in question is a monolith - which has been in production for many years. It is fair to assume that multiple updates were made to the application as bug fixes, minor updates which are not documented anywhere but in the codebase.

  2. A downside of creating a copy and removing implementation related to the existing vendor product - and replacing it with new vendor product - would have been that we may have lost those tactic business rules.

  3. As has been pointed out in the responses below, going ahead with Option #2 would have resulted in a cost associated with business change activities due to introduction of a manual process to select which application to use. This in-turn would have resulted in re-training of multiple team.

  4. From an infrastructure point of view - there was a possibility of framework/version incompatibility - when deploying the copy (from Option#2) to our latest standard infrastructure stack. If going ahead with Option #1 it would have been a matter of re-deploying to the existing (albeit non-standard) stack as opposed to re-platforming the entire application to the standard stack (in case of option #2). An alternative would have been to spin up the non-standard stack for option #2 but that would have meant maintenance overhead.

  • 1
    Is the off-the-shelf software essentially a plug-in? Something that is remote controlled from within your app? Are the integration points abstracted in any way? Can they be? Jan 29 '18 at 17:31
  • My thoughts seem to align with Berin's questions and leaning towards an option #3, which is to turn your legacy codebase into a library of sorts if possible/practical to be called from your new application by whatever means possible: interprocess communication, a dylib API, etc.
    – user204677
    Jan 30 '18 at 1:26
  • @berin - the application is a UI wrapper on top of information that is manipulated by the off-the-shelf vendor product. Integration points are not abstracted at this point but there is a recognition that this must happen. So work is underway to identify dependencies and isolating/abstracting them.
    – nesh_s
    Jan 30 '18 at 8:43
  • @teamupvote - thanks. but would you have the library used as a new component in the original application (by way of software reengineering) or you see the library being used in a copy - a duplicate application (NewApp1)?
    – nesh_s
    Jan 30 '18 at 8:44
  • 1
    i am also inclined to proceed with option #1 and your previous comments summarize my way of thinking. in our case the desire to proceed with option #2 is driven by the desire to de-risk the impact on business capability. by way of having two applications running in parallel (technical implementations aside) we could have the old functionality available as-for business users. the downside is we are giving business users more than they asked for i.e. two applications both doing something slightly different and its not going to be easy to take one app away when the time comes.
    – nesh_s
    Jan 30 '18 at 9:06

I'm assuming you have a small team and a limited budget, so my answer assumes the following is true:

  • Maintaining 2 separate applications would be a big strain on the team
  • The work to integrate the new product is non-trivial
  • The old product is nearing end of life or is obsoleted by the new product which does the same job better

At this point you have to take stock in what you have, and where the integration points happen. In the comments you mentioned that your app provides visibility into the data that is manipulated by your tool. So I would start out by ruling out possibilities.

  • If you were to run both products on the same data at the same time do you have consistent results? (if not, that rules out option #2 at the beginning)
  • How much impact would forcing users to make a choice every time they process something be. One or two times a day may not be a big impact, but when it has to happen all day long the impact can significantly impact the amount of work the users can get done.
  • Understand how each program communicates its results and what the integration opportunities are.

Assuming that both options are still on the table, you'll have to do a series of targeted rewrites. To do this effectively, you'll need version control software if you don't already use it. Here's how it will go down:

  • Pick one goal and time-box it. It should be something you think you can achieve in that time.
  • Write down the tasks you think will need to be taken to achieve the goal
  • If it looks like you are going down a rabbit hole and the changes are more extensive than you first thought: write down the barrier a step above the task you just were working on and roll back your changes!
  • If you found a barrier to your first task, that becomes your new task. Repeat until you get your goal done.

Your time-box is important. This is basically the amount of time you can afford to be wrong. If you beat the time, great. But if time is up and you are only a portion of the way through, you either misjudged or there are other steps that need to be taken first. The time box helps you be honest about whether you are in a rabbit hole or not.

As a first goal, you might look at what interface you need from the perspective of your application to the third party tools. Then separate the logic so that your application calls the right methods in the interface and the implementation calls invokes the right calls to your current third party tool. Implementing a second implementation should be easier once you learn from that process.

  • [switching between applications] "one or two times a day may not be a big impact". Switching every 5 minutes may not be a big burden if there is a clear conceptual distinction amongst the users - but if it becomes subtle to evaluate which application needs to be used, or if both applications need to be used for what a user would regard as one piece of work (particularly if each application has a context that has to be set up or inputted, like a customer number or an account number), that's when users will start to beg for mercy.
    – Steve
    Jan 30 '18 at 14:38
  • @Steve, perhaps your users may be different than mine. I've had experience where adding another step to a repetitive process was intolerable. Without more information about how exactly the users are expecting to use the application or what the 3rd party tools are, I have to assume that the threshold where the additional step becomes a burden is less than you originally think. Jan 30 '18 at 14:43
  • I agree absolutely it is a judgment about how it will affect the work process - I'm just making the point that it is not the frequency of switching screens itself that grinds users down, it's the more subjective perception about whether it is easy to do so and whether it interrupts (or erodes the efficiency of) the work process. In other words, it requires more of a human factors analysis than a time and motion analysis - for example an extremely repetitive switch will be tolerable if it can be done on muscle memory with a hotkey, but users will howl if they have to pay close visual attention.
    – Steve
    Jan 30 '18 at 15:23
  • @BerinLoritsch very insightful and detailed. thank you.
    – nesh_s
    Jan 30 '18 at 16:41

Unless end-to-end automatic testing is easy i would go for option 1.

@BerinLoritsch has good points, my order of steps would be to:

  1. Reduce dependencies: Abstract all communication to interfaces (for everything check if this is possible with App2)
  2. test if code still works on App1
  3. Optionally: Try to write as many unit tests as possible that test against interfaces but on App1 (so with specific data that works for this test and is properly reset)
  4. Build implementation with App2
  5. Test new implementation with the same unit tests, since it is build against the interface this should be easy and a quick gain

On the other hand. both Apps cannot follow/implement the same interface. option 2 is your only go. Make sure you properly research your code before you start.

thus step 0 should be: map (make a scheme of) all current communication between your app and App1 check if it is possible to be replaced with App2.

  • 1
    thank you for your response. its a legacy application - a monolith - with no tests. the first work item for the dev team has been (for the past few weeks) is to add retrospective tests to cover features that constitute the MVP.
    – nesh_s
    Jan 30 '18 at 16:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.