[Software Architecture] Memento is an anti-pattern — Part 3: Concurrency

Guillaume Bonnot
3 min readFeb 3, 2020

--

In this series, we will explore well know design patterns and how to (not) use them when writing high performance software.

In this article we will take a look at the implementation of a concurrent producer/consumer pattern and compare how it interacts with the Memento and Post State patterns.

Application

Let’s take a simple concurrency scenario using the previous implementations of the AccountService.

The producer thread will create 2 accounts, deposit 10000 BTC to the first account and 10000 USD to the second account, then exchange 1 BTC for 1 USD between where the first and the second account, 10000 times.

After the exchanges are all processed, the first account should have exchanged all their 10000 BTC for 10000 USD with the second account.

Consumer Service

The consumer thread (Supervisor Service) will be notified when an account is updated in the producer thread, and it will check that the total sum of BTC and USD should always be 10000 for any given account.

Account Service

The account service interface now has a callback you can register to be notified when an account is updated.

Post State

The modifications required to integrate the account updated callback are straight forward because post state already has the commit logic.

Has expected, the program runs smoothly because post state is thread safe by design and each account is immutable.

Memento

The account service implementation for memento does not have the commit logic, so we need to change the logic of method that modifies the account to call the account updated callback if there was no error.

The naive implementation of the program using memento does not work !

Because we are using mutable accounts, the consumer thread can read the state of account in the same time that it is modified by the consumer.

The best way to fix this problem is to make a copy of the account we send to the consumer. This copy will only be read and should not be modified, so it will de facto become immutable.

Conclusion

A design pattern is a general solution to a commonly occurring problem.

Memento is an anti-pattern because it makes you think the problem should be solved by adding extra logic on how to handle your mutable objects, when your problem could be solved by simply making your objects immutable.

This is the last article of this series, feel free to take a look at part 1 and part 2.

The complete source code for the example can be found on github.

--

--