0

I have a financial application that processes 'bonds'. I need to

  1. Model the application to avoid an anaemic model (which i understand is bad).
  2. Instantiate different implementations depending on the type of bond.

The system gets instructions from an external system, and applies the instructions to the specified bond. hence i have an Instruction entity

Instruction[Id,BondReference,Action,Value]

e.g. of an instruction to vote 'yes' for a resolution passed on the bond

Instruction
{
    BondReference: Bond1,
    Action: Vote
    Value: VoteYes
    ResolutionReference: Resolution1
}

and a Bond entity

Bond
{
    Id: 1,
    Reference: Bond1
    Resolutions: [
                     {Resolution1: We have resolved to increase our stake in Google},
                     {Resolution2: We have resolved to fire the CEO}
                     ...
                 ]
    Instructions: [Inst1,Inst2,Inst3...]
}

However, an instruction usually does more than just one thing (it is effectively many instructions in one), e.g. an instruction to cancel a previous instruction, that would mean, firstly, it cancels a previous transaction, then certain values need to be recalculated. Also, a single instruction can come overloaded, it can be to cancel a previous instruction as well as vote for a resolution.

I have been advised to use a domain service to process a new instruction.

BondService
{
    public void Apply(Instruction newInstruction)
    {
        var bond = _bondRepository.GetByReference(newInstruction);
        bond
            .RecalculateNominalValue(newInstruction)
            .CalculateInterest(newInstruction)
            .CancelInstruction(newInstruction)
            .Approve(newInstruction);
    }
}

The problem i see with this structure is that for each instruction, all methods are called even if the method is not relevant. I could use some if statements but then the code would look untidy.

Now my question is,

  1. Is this the best way to model?
  2. And for the calculation, depending on the bond type the calculation differs. So i want to implement polymorphism. I have been told that i need to use a factory to instantiate the correct implementation. Is this the best approach?

For BondType 1,3,5 i use calculationA, for bondType 2,7... i need to use Calculation B. how do i INSTANTIATE the different calc types??? NB, i am well versed with polymorphism, however, i have been unable to find solid examples of how to instantiate the correct implementation. thnx for reading this far...

sawe
  • 1,141
  • 14
  • 24

1 Answers1

2

A few thoughts:

  • Instruction seems like it serves the purpose of a command DTO and a value object used to store an audit trail. Decouple these two concepts.

  • The Bond entity, as is typical for financial domains, calls for event sourcing. In effect, you're already there by storing all instructions and resolutions. Make it explicit. You may not need to store all the instructions if you instead make any changes to a bond explicit as domain events. A single instruction can result in multiple events.

  • The example of a domain service is actually an application service or a command handler. An application services coordinates repositories and delegates to domain objects. To best implement an application service, delegate as much business logic to domain objects, a Bond in this case. Therefore, have the Bond entity decide exactly which sub-behaviors to call so that the application service only calls a single method on the entity.

  • To provide polymorphism, create a value object to allow representation of different bond types. Have the Bond entity delegate to this polymorphic bond type value. You may need a factory to initially instantiate this bond type VO, but once it is associated with the Bond entity, you no longer need to call the factory, the Bond simply references the bond type VO.

eulerfx
  • 36,769
  • 7
  • 61
  • 83
  • thanx for the response, the one thing i failed to mention is that this is a brownfield project and we are slowly converting it to a new application and in the meantime we will use the existing front-end, hence we cannot change the db structure etc. So i will keep the suggestion of event sourcing in mind (but will probably(most likely) not implement now) because i have to do some reading on the topic etc. What i liked most is that 1 instr = multiple events(i would most likely be creating multiple commands from 1 instruction). i will mark as answer as soon as i implement your suggestions – sawe May 27 '13 at 06:36
  • the reason i would need the Factory is because about 3 bondTypes use one calculation, and one bondType uses the other calculation. so in the long run, bondTypes could be added that use a different calculation altogether, so *1 bondType != 1 calculation*. so using the bondType to do the calculations would mean that i duplicate the calculations in different places. makes sense? or can i explain further – sawe May 27 '13 at 06:45