DEV Community

Cover image for How I used the Strategy pattern in AL to build a maintainable Business Central extension
Yahya Touil
Yahya Touil

Posted on Edited on

How I used the Strategy pattern in AL to build a maintainable Business Central extension

Most AL developers have written this at least once:

case Strategy of 
 Standard: 
   Score := CalculateStandard(...); 
 Weighted: 
   Score := CalculateWeighted(...); 
end;
Enter fullscreen mode Exit fullscreen mode

It works.

Until you add more strategies.

Then the calculator starts knowing about every scoring algorithm, and every new strategy means modifying existing business logic.

For my AL Strategy Pattern Risk Engine, I wanted to separate the scoring algorithms from the calculator.

The core pattern is simple:

Interface + Enum = selectable strategy

interface ICFRRiskStrategy
{
    procedure CalculateScore(Customer: Record Customer): Decimal;
}
Enter fullscreen mode Exit fullscreen mode

Each scoring strategy implements the same interface.

The TY Risk Strategy enum defines the available strategies and maps each enum value to its corresponding implementation.

The calculator can then work with the selected strategy instead of knowing which specific implementation is being used:

Score := Strategy.CalculateScore(Customer);

The project currently includes two strategies:

Standard
→ returns a fixed baseline score of 50.

Weighted
→ calculates the score using customer information such as blocked status, missing credit limit, and balance due exceeding the credit limit.

The extension also includes:

Configurable scoring rules through a setup table instead of hardcoded weights and thresholds.
Risk levels that classify the resulting score as Low, Medium, or High.
Risk Assessment Log that records each assessment, including the customer, strategy, score, level, user, and date/time.
A calculator that handles validation, strategy execution, score classification, and logging.
A read-only assessment history providing an audit trail of the evaluations.

The main thing I wanted to demonstrate with this project is how AL interfaces and enum implementations can be used to implement the Strategy pattern without putting every scoring algorithm inside one calculator.

It keeps the scoring logic separated and makes the extension easier to extend when another strategy is needed.

Full architecture breakdown 👉 https://yahyatouil.com/posts/building-al-strategy-pattern-risk-engine/

Source code 👉 https://github.com/yahyatouil-dev/bc-al-strategy-pattern-risk-engine

Top comments (0)