In this blogpost I continue my series of design patterns for AL.
This time I write about a simple pattern which could make the readability of your code much better. I’m talking about the “Template method pattern”. The pattern defines the skeleton of a process without implenting it. The real implemenation is handelt in another codeunit.
The big advantage of this pattern is that it helps us to solve similar problems with a similar solution
In AL you need at least 3 objects to implement the pattern:
- A template codeunit
- An Interface which provides the needed procedures
- And an implementation for the Template
The template codeunit
The template codeunit defines the skeleton of a solution without implementation. In the following example I’m implementing a data export
codeunit 50000 ExportTemplate { procedure ExportData(export: Interface IDataExport) begin if not export.CheckData() then exit; if export.GetLinesToExport() then begin repeat export.ExportLine(); until not export.NextLine(); end; export.finish(); end; }
The interface
Now that we have the skeleton we need the interface which is used in the codeunit above
interface IDataExport { procedure CheckData(): Boolean; procedure GetLinesToExport(): Boolean; procedure ExportLine(); procedure NextLine(): Boolean; procedure Finish(); }
That’s the whole and simple pattern, just to have a complet sample I add one implentation for the pattern
Implementation Example
Here is the implementation of the interface
codeunit 50001 SalesHeaderExport implements IDataExport { procedure SetSalesHeader(DocType: Enum "Sales Document Type"; No: Code[10]) begin SalesHeader.Get(DocType, No); end; procedure CheckData(): Boolean begin SalesHeader.TestField(Status, Enum::"Sales Document Status"::Released); end; procedure GetLinesToExport(): Boolean begin SalesLines.SetRange("Document Type", SalesHeader."Document Type"); SalesLines.SetRange("Document No.", SalesHeader."No."); exit(SalesLines.FindSet()); end; procedure ExportLine() begin //Generate Exportdata here end; procedure NextLine(): Boolean begin exit(SalesLines.Next() > 0); end; procedure Finish() begin // Send or Save data here end; var SalesHeader: Record "Sales Header"; SalesLines: Record "Sales Line"; }
And here is the usage
codeunit 50002 ExportOrders { procedure ExportOrder(DocType: Enum "Sales Document Type"; No: Code[10]) var export: Codeunit ExportTemplate; exportImpl: Codeunit SalesHeaderExport; exportInt: Interface IDataExport; begin exportImpl.SetSalesHeader(DocType, No); exportInt := exportImpl; export.ExportData(exportInt); end; }
Cooles Muster
Pingback: Using the “Template method pattern” in AL | Pardaan.com