How to transform one aggregate to another in DDD

  softwareengineering

Where I work we’ve got wallets with transactions (i.e. every transaction belongs to a single wallet). Currently we’re working on an addition of transfers between wallets. As a part of this, a new Transfer concept has been added to the ubiquitous language dictionary.

One functional requirement is to give users the option to change a transaction to a transfer. Because a regular transaction and a transfer have got different validation rules (such as who can edit the aggregate, which attributes are editable,…) and because transfers are a different concept from a transaction, I have created a separate aggregate to represent a transfer.

Now I am however facing a problem how to store the data. I have a command handler with a call to a Transaction.changeToTransfer returning a Transfer instance. I am fine with this approach, but where I got stuck was the persistence.

Upon changing a transaction to a transfer, the original regular transaction should become a transfer and I am not sure where exactly this transformation is supposed to happen.

One of the ideas that came into my mind was not to have a transfer concept as a separate aggregate at all and represent the transfer relationship as internal values of a regular transaction, however I don’t really like the idea of a transfer having access to methods of a regular transaction which the transfer should not have at all, hence why I chose the path of having a separate aggregate.

An example of a behaviour difference is: a user can edit pretty much any attribute on a regular transaction, on the transfer only a memo field may be edited and only by the current “owner” of the transfer. Seems like introducing checks to all other update methods involving if(isTransfer()) { ... throw ... } seems wrong.

Which modelling approach should I take tackling this concept and transforming one aggregate into another?

16

This sounds like inheritance in your Domain Model.

Transfer derives from Transaction because it is a specific kind of Transaction with potentially more information and behaviour.

The new question now is:

How do I model inheritance in my persistence?

There are several ways of doing this, but it will depend on the kind of database you’re using.

IIRC, Entity Framework used to accomplish this with Relational Databases by having one table for each type, and derived type tables shared primary keys with the base type tables.

So, in your example, you would have a Transaction table and a Transfer table, and each Transfer record would have a corresponding Transaction record with a matching primary key.

5

LEAVE A COMMENT