Search code examples
javadesign-patternsframeworksopen-source

How to calculate, control customer credit and update it?


I have a financial system and I have to design a module for save, update and control limitation. You can know each customer has a UserID and each UserID has a maximum amount of credit per day. For example, UserID = 12 has MaxAmountPerDay = 10$ and CurrentAmountPerDay.

At first, I wanted to design a simple module and define a table as follows:

  User ID | MaxAmountPerDay | CurrentAmountPerDay
-------------------------------------------------
  12     | 10              | 0
  25     | 100             | 84

Now you can imagine when the customer with UserID = 12 has done a transaction I have to control if the transaction amount + current amount > max amount then throw an exception else I have to do the transaction and update current amount and when an exception happened after updating I have to rollback the update operation.(update and rollback are in different database transactions so the rollback is the same update with new amount)

Before I do this design I decided to look up for a better solution or even an open source framework for doing that because I guess my customer's requirements will change in future, for example maybe they will need to MaxAmountPerMonth, or some more requirements which I don't know now.


Solution

  • Data may come from a database table or from any support service, it is not really a problem.
    You simply need some data to valid user transaction.

    About framework, you could use a BPM but with such a small requirement, it is an overhead.
    A thing that you may do to improve the validation rules maintenance is decoupling each specific rule.
    Today, you have one validation rule, but in the future, you will very probably have multiples rules that may invalidate the user transaction.
    To handle them, you could simply define a chain of rules :

    TransactionRule rulesChain;

    that rely on a validation interface :

    public interface TransactionRule{
      void valid(UserInformation userInformation) throw ValidationException;
    }
    

    Each element of the chain is so a implementation of this interface.
    As you invoke valid() on the rules chain, it applies the first rule.
    If the rule is respected by the user information, it passed the hand to the next rule.
    And so for... And as soon as an element throw ValidationException, it means that the rule is not respected and so the validation is over and the transaction has to be canceled.

    The proposed way may be seen as a light version of the chain of responsibility pattern.
    I said "light" as the order of rules execution should not matter in your case while it generally matters in this pattern.