0

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
  • A transfer is a specific type of transaction. Apr 19, 2018 at 15:53
  • I was going to say what what Robert said, but in the form of a question. It sounds like you are taking a generic transaction and promoting it to the specialised "transfer" transaction. Is this correct?
    – MetaFight
    Apr 19, 2018 at 15:55
  • What would happen if somehow, a user would want to perform an action on a transaction that was transformed into a transfer? I try to see if there are different concepts or not. Apr 19, 2018 at 16:13
  • @RobertHarvey I agree that a transfer really is a transaction going to or from somewhere out of/into a specific wallet, however in this current scenario, those are considered to be different types. Kind of as if a transfer was superior to a transaction and transaction was merely a representation of the transfer while transfer itself had a special behaviour.
    – Andrew
    Apr 19, 2018 at 18:40
  • @MetaFight, exactly that.
    – Andrew
    Apr 19, 2018 at 18:40

1 Answer 1

1

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
  • All true. The real question is, is that what the OP really needs? Apr 19, 2018 at 18:50
  • You may be on to something. This comment makes it sounds like there may be larger domain modelling issues that need to be addressed first.
    – MetaFight
    Apr 19, 2018 at 18:56
  • I don't think inheritance solves this problem. By making a transfer a child of a transaction, a transfer would inherit the transaction's methods as well, which, as pointed out in the original post, based on the business requirements are not supposed to be even available. I don't like the idea of polluting the public API of the transfer class with unusable, i.e. those to be disabled, transaction methods just by inheriting a transaction.
    – Andrew
    Apr 19, 2018 at 19:18
  • which is why I said there may be a larger modelling problem. Those methods that are not relevant to a Transfer should maybe reside on another derivation of Transaction.
    – MetaFight
    Apr 19, 2018 at 19:19
  • Could you perhaps in your answer, please, expand on what you mean by another derivation? A simple example would be greatly appreciated. I don't understand what you mean by the derivation concept.
    – Andrew
    Apr 19, 2018 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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