3

On my first part-time programming gig during college, I dealt with a large-ish web application responsible for handling a periodic event hosted by our client, largely a plain CRUD snoozefest with a number of forms for the users to fill out.

The forms change between events, with most forms having a small amount of changes done to them - some fields added, removed, and adjusted, e.g. an open question split into two or a choice changed from radio to checkboxes. All forms from previous editions must be accessible at all times.

The code quickly became riddled with base classes such as:

veryImportantFormModel
veryImportantFormModelLegacy
veryImportantFormModel2017

consisting mostly of copy-pasted code throughout many layers of the backend and frontend. Which to my clueless junior developer eyes looks like a quick way to accumulate unmanageable amounts of debt, and hopefully is not the go-to solution for what I assume is a very common scenario.

What would be a saner way of doing things?

j4nw
  • 141
  • 5
  • 3
    Possible duplicate of [I've inherited 200K lines of spaghetti code -- what now?](https://softwareengineering.stackexchange.com/questions/155488/ive-inherited-200k-lines-of-spaghetti-code-what-now) – Pieter B Mar 02 '18 at 11:29
  • I am also curious (as is @Ewan) about the "All forms from previous editions must be accessible at all times" requirement. Do you mean the *schema* of previous versions? (i.e. what were the radio options, field type ,etc) - or that literally "all forms" (previous versions) "MUST" be *able to be submitted* at all times (even years after the event has past, etc). – Tersosauros Mar 02 '18 at 11:39
  • I believe as it is right now, the client wanted everything live, and there was no major pushback from our side (though this was before my time). I would appreciate a followup answer explaining how to properly expose decommisioned schema in a user-friendly read-only fashion. – j4nw Mar 02 '18 at 11:46

2 Answers2

4

If all those older editions must be kept live, I think your best shot is to

  • isolate the classes which belong to the specific event

  • put them in a namespace indicating the specific event and the date or month when it happens

(of course, your environment and programming language supports namespaces, I assume?).

Then you can have as many versions of veryImportantFormModel as you like live in parallel, each one living in a different namespace.

Note this kind of technical dept is manageable when chances are high you don't have to touch the older code for events in which happened in the past. Maintenance is only a problem for code which has to be actively maintained, not for code which is just "running".

This is very similar to the situation where you have a product with versions 1.0, 2.0, 3.0 and 4.0, each one based on the previous one, and each of the four deployed and in use in parallel. When you start with developing version 4.0, you may be have an obligation to to some minimal maintenance at the 3.x line, and maybe you need to deploy versions 3.1 and 3.2. But when 4.0 goes live, issue request for the previous lines will typically drop down, and new features will only be added to the newest version. In a contract-based situation, you can also make this model part of the contract.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • 2
    +1 for "Maintenance is only a problem for code which has to be actively maintained". I think the (valid, but undesirable) "code and forget" method is too often frowned upon for theoretical reasons only. – Tersosauros Mar 03 '18 at 00:43
3

The key thing that stands out for me is :

"All forms from previous editions must be accessible at all times."

I guess you mean live in the application? If so, then yeah you are going to need all those files, the only thing you can really do is to make a naming convention and version them. Push hard to Decommission old forms if possible.

I would resist the urge to refactor them into some inheritance hierarchy. Although OOP might seem to suggest that this is the way to go, the problem is that these changes are not driven by a known business case, but by evolving requirements.

In those conditions you would potentially have to refactor huge amounts of code if you link the versions together by inheritance and some crazy unexpected change comes along.

If you can challenge the requirement for all the forms to be available, then I would say that best practice is to have a migration path for the objects.

The you can keep only the latest version of the form and migrate the old data to fit it.

Edit: How to propose decommissioning in a user friendly way.

This is a tricky one because maintaining the forms is a problem for you and not the client.

I would say the best approach is to evaluate the cost of maintaining multiple forms and include it in the cost of the software.

This makes it the clients problem, you can then say. "We can give you a lower price if we don't have to support those old forms."

However, you need to be honest with yourself about the cost of maintenance. Chances are its just costing you disk space. Keep track of bugs which you can trace back to being caused by the old forms and Time spent testing the old forms work when you make changes.

Ewan
  • 70,664
  • 5
  • 76
  • 161