Persistent Strategies

I’ve just finished working on a cash management system. The core of what the system does is listen to messages produced by various sources and record a transaction (i.e. a debit and a credit) between two accounts.

For example, the system will listen to trade messages produced by our trading system and charge a trade fee to the client. This involves debiting the client and crediting the Fee house account.

This seems innocent enough, but to create a transaction you must have a reference to each of these accounts.

The client’s account is easy enough to find as all the required information is supplied in the trade message. But what about the house account ? How does the system find an instance of the house Account ?

One could do something like this, store the account number in a constant somewhere:

Account account = accountService.getAccount(FEE_HOUSE_ACCOUNT_NUMBER);

// create Transaction with client and house account

This is pretty bad IMO because there is duplication and “hard coding” ( even if it is in a properties file) of what house account numbers there are.

If you didn’t want to store the account number in code (or in a properties file which is almost as bad) you could add it to the static data for that transaction type:

@Entity
class TransactionType {
    String name;
    Account creditAccount; // this could be null to indicate that the account is based on the message
    Account debitAccount; // this could be null to indicate that the account is based on the message
    //...
}

then you would just find the TransactionType and the get the credit or debit account.

This would work, but it is very specific, since sometimes we may want to find the debit / credit account in a different way (e.g. “find the loan account associated with the client’s cash account”).

Enter the Persistent Strategy.

Basically, the idea is that rather than store links directly to Accounts in your static data, store a Strategy to obtain the right Account.

@Entity
public class TransactionType {</code>

    private String type;

    @ManyToOne
    private AccountAllocationStrategy toAccountStrategy;

    @ManyToOne
    private AccountAllocationStrategy fromAccountStrategy;
}

@Entity
@Inheritance
public abstract class AccountAllocationStrategy {
    public abstract Account getAccount(Transaction transaction);
}

What we’ve done is added a strategy for find the from / to account and we can have specific implementations:

@Entity
public class FixedAccountAllocation extends AccountAllocationStrategy {

    @ManyToOne
    private Account account;

    public Account getAccount(Transaction transaction) {
        return account;
    }
}

@Entity
public class InvestorAccountAllocation extends AccountAllocationStrategy {

    @Override
    public Account getAccount(Transaction transaction) {
        return transaction.getInvestorAccount();
    }
}

(there are a few more implementations I’ve left out for brevity).

You could achieve a similar effect by using a code of some sort (e.g. an enum) to denote the strategy and look up the strategy instance via Spring, but I like this better since it is more transparent and doesn’t require involving other frameworks. The major problem with the Spring approach is you’ve still got to specify the account numbers somewhere in your Spring context file which is duplication (once in the Spring file, once in the database) which, we all know, is bad :)

It might seem like abusing entities or the domain model but it is a really powerful pattern. Think of these entities as your rule domain. JPA makes mapping entities really easy and the number of strategies are finite so you can be quite creative in your mapping and inheritance hierarchies. You can also fully cache the strategy entities so performance will not be an issue.

We use this pattern in a few places in the system and it has made the code much cleaner and maintainable.

Advertisements