Partitioning of Models with Faktor-IPS
Cross-Line Premium Computation Using the Derived Union Association
Since we can now access all coverages in the cross-line class Contract, we can also implement parts of the premium computation in a cross-line manner. The annual base premium of the Contract always equals the sum of the premiums of its coverages. The calculation of the premium for the individual Coverage is then, of course, again line- and coverage-specific.
Adding a Concrete and an Abstract Method to Coverage
In order to be able to call the premium computation of coverages from within the cross-line model, we first make sure that the derived attribute (derived by explicit method call) annualBasePremium of type Money is correctly configured in the class Coverage, and then add two new methods. To do so, we go to the Behaviour tab in the policy component type editor of Coverage and click New in the Methods section. We configure the first method ("computeAnnualBasePremium") with a void return type in the dialog as follows:
The second method is marked as abstract and uses the return type Money.
Faktor-IPS generates the following abstract method in the Coverage class:
public abstract Money computeAnnualBasePremiumInternal();
We call this method in our implementation of computeAnnualBasePremium and set the code to @generated NOT.
/**
* @since 1.0
*
* @generated NOT
*/
@IpsGenerated
public void computeAnnualBasePremium() {
annualBasePremium = computeAnnualBasePremiumInternal();
}
Implementing the Computation Method in Contract
We can now implement the calculation of the annual base premium in the class Contract. Analogously, we add a non-abstract method computeAnnualBasePremium there. In the generated Java code we replace the empty implementation with the following logic.
To prevent the Faktor-IPS code generator from overwriting our implementation during a build, we add NOT to the @generated annotation:
|
/**
* @since 1.0
* @generated NOT
*/
public void computeAnnualBasePremium() {
getCoverages().forEach(Coverage::computeAnnualBasePremium);
annualBasePremium = getCoverages().stream()
.map(Coverage::getAnnualBasePremium)
.collect(Money.sum())
.orElse(Money.NULL);
}
Overriding the Method in HomeBaseCoverage
In the line-specific coverage classes we add the method via the IPS editor as well. To do so, we go to the Behaviour tab and click Override to select the method defined in the superclass. We then implement the concrete logic in the Java editor. For HomeBaseCoverage the implementation looks like this, for example:
/**
* @since 1.0
*
* @generated NOT
*/
@Override
@IpsGenerated
public Money computeAnnualBasePremiumInternal() {
var rateTable = getRateTable();
if (rateTable != null) {
var row = rateTable.findRowNullRowReturnedForEmptyResult(homeContract.getRatingDistrict());
return homeContract.getSumInsured()
.divide(1000, RoundingMode.HALF_UP)
.multiply(row.getPremiumRate(), RoundingMode.HALF_UP);
}
return Money.NULL;
}
Here too, @generated must be extended with NOT so that the code generator does not regenerate the method.