What options are there in the Spring4D framework that we don’t know about, but are very usable? Well, actually quite a lot. One of them is the Factory Pattern. It comes in very handy when you want to apply the open/closed principle. Your code is open for extension, but closed for modification.
A classic example is working with enumerations or numbers that indicate a certain state. This quickly creates all kinds of conditional structures that have to be adapted as soon as a new status or value is added. In the example below, certain code is executed depending on an invoice status. To split the code, the factory pattern was applied.
This is the definition of invoice and status:
type {$SCOPEDENUMS ON} TInvoiceStatus = (New, Sent, Overdue, Paid); {$SCOPEDENUMS OFF} TInvoice = class public function Status: TInvoiceStatus; end;
type TProcessInvoiceProc = reference to procedure(const Invoice: TInvoice); TInvoiceProcessor = class private FFactory: TFactory<TInvoiceStatus, TProcessInvoiceProc >; procedure InitialiseFactory; end; procedure TInvoiceProcessor .InitialiseFactory; begin FFactory := TFactory<TInvoiceStatus, TProcessInvoiceProc >.Create; FFactory.RegisterFactoryMethod(TInvoiceStatus.New, ProcessInvoiceNew); FFactory.RegisterFactoryMethod(TInvoiceStatus.Sent, ProcessInvoiceSent); FFactory.RegisterFactoryMethod(TInvoiceStatus.Overdue, ProcessInvoiceOverdue); FFactory.RegisterFactoryMethod(TInvoiceStatus.Paid, ProcessInvoicePaid); end;
function TInvoiceProcessor .ProcessInvoiceNew: TProcessInvoiceProc; begin Result := procedure(const Invoice: TInvoice) begin ShowMessage('This is a new invoice'); end end;
Applying the factory is then easy and goes as visible in the code below:
procedure TInvoiceProcessor .ProcessInvoice(const Invoice: TInvoice); begin if FFactory.IsRegistered(Invoice.Status) then begin var Process := FFactory.GetInstance(Invoice.Status;) Process(Invoice); end; end;
Contact
GDK Software UK
(+44) 20 3355 4470GDK Software USA
+1 (575) 733-5744