In this article, we will solve the problem that requires applying all of those three patterns. Before you continue to this article I suggest you to read my three articles on those patterns. In those articles I solved parts of the problems that is mentioned here. Here are the links: state, visitor, memento.

Problem

Our team developed a software solution dedicated to calculating insurance costs for an insurance company. There were two use cases when customers interact with an application:

  • When you buy an insurance
  • When you have an incident

In both cases, you are prompted to populate some forms. For example, when you buy an insurance, you first populate basic info about yourself, then in the next form you populate info about your car, then you select the kind of insurance, etc.

In case of an incident, you populate one form that shortly describes the incident(date and time when the incident happened, who was driving the vehicle, does incident happened in foreign country, etc.), then based on what was populated in the first form you should go to either form that is designed for domestic incidents or form that is designed for foreign incidents, etc.

Also, it was important to remember form history so reverting to the past states is possible!

Of course, when every form is submitted, we must process it on the backend side (save data in the database or send a message to the Kafka, depending on the form). But processing the form is not the only operation that we want to do with our form! There is also an archive operation when some form is not edited for 1 year, this means that data of the form should be changed in some way, according to archiving rules.

Explanation why those three patterns for this problem

Visitor: We have a family of classes(we have Form interface and for every specific form we have one class that implements that interface) and we need to support two operations(archive and submit) for every class in the family!

State: Our program behaves differently based on the state of the wizard. If we just started our wizard and populated IncidentInfoForm, our software will tell us what is the next form based on the data in the IncidentInfoForm that we just populated. Also, if program expect us to populate IncidentInfoForm and we try to submit CreditCardInfoForm, exception will be thrown. On the other hand in some different state of the wizard submitting CreditCardInfoForm will be processed normally.

Memento: At any stage in the wizard, we want an ability to roll back to some previous state. For example: “Retrieve the state that was valid on 4.7.2020” or “Retrieve the state after the last modification made by John Doe.”.

The code

I will just present the code without so much explanation. In order to udnerstand the code, you should check state, visitor, memento posts. The link to the repository where you can check the code is here.