Welke opties zijn er in het Spring4D framework die we niet kennen, maar die wel heel bruikbaar zijn? Nou, eigenlijk best veel. Eén van die dingen is het Factory Pattern. Het komt erg van pas als je het open/closed principe wilt toepassen. Je code wel open voor uitbreiding, maar gesloten voor aanpassing.
Een klassiek voorbeeld is het werken met enumeraties of getallen die een bepaalde status aangeven. Er ontstaan dan al snel allerlei conditionele structuren die aangepast moeten worden zodra er een nieuwe status of waarde bijkomt. In onderstaande voorbeeld wordt afhankelijk van een factuurstatus bepaalde code uitgevoerd. Voor het opsplitsen van de code is het factory pattern toegepast.
Dit is de definitie van de factuur en 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;
Het toepassen van de factory is dan eenvoudig en gaat zoals zichtbaar in onderstaande code:
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