Que opções existem na estrutura do Spring4D que não conhecemos, mas que são muito úteis? Bem, na verdade, são muitos. Um deles é o Factory Pattern. Ele é muito útil quando você deseja aplicar o padrão open/closed principle. Seu código está aberto para extensão, mas fechado para modificação.
Um exemplo clássico é trabalhar com enumerações ou números que indicam um determinado estado. Isso cria rapidamente todos os tipos de estruturas condicionais que precisam ser adaptadas assim que um novo status ou valor é adicionado. No exemplo abaixo, determinado código é executado dependendo do status de uma fatura. Para dividir o código, foi aplicado o Factory pattern.
Essa é a definição de Invoice e status:
1 2 3 4 5 6 7 8 9 |
<span style="color: #000080; font-weight: bold;">type</span> <span style="color: #008800; font-style: italic;">{$SCOPEDENUMS ON}</span> TInvoiceStatus = (<span style="color: #000080; font-weight: bold;">New</span>, Sent, Overdue, Paid); <span style="color: #008800; font-style: italic;">{$SCOPEDENUMS OFF}</span> TInvoice = <span style="color: #000080; font-weight: bold;">class</span> <span style="color: #000080; font-weight: bold;">public</span> <span style="color: #000080; font-weight: bold;">function</span> Status: TInvoiceStatus; <span style="color: #000080; font-weight: bold;">end</span>; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span style="color: #000080; font-weight: bold;">type</span> TProcessInvoiceProc = reference <span style="color: #000080; font-weight: bold;">to</span> <span style="color: #000080; font-weight: bold;">procedure</span>(<span style="color: #000080; font-weight: bold;">const</span> Invoice: TInvoice); TInvoiceProcessor = <span style="color: #000080; font-weight: bold;">class</span> <span style="color: #000080; font-weight: bold;">private</span> FFactory: TFactory<TInvoiceStatus, TProcessInvoiceProc >; <span style="color: #000080; font-weight: bold;">procedure</span> InitialiseFactory; <span style="color: #000080; font-weight: bold;">end</span>; <span style="color: #000080; font-weight: bold;">procedure</span> TInvoiceProcessor .InitialiseFactory; <span style="color: #000080; font-weight: bold;">begin</span> FFactory := TFactory<TInvoiceStatus, TProcessInvoiceProc >.Create; FFactory.RegisterFactoryMethod(TInvoiceStatus.<span style="color: #000080; font-weight: bold;">New</span>, ProcessInvoiceNew); FFactory.RegisterFactoryMethod(TInvoiceStatus.Sent, ProcessInvoiceSent); FFactory.RegisterFactoryMethod(TInvoiceStatus.Overdue, ProcessInvoiceOverdue); FFactory.RegisterFactoryMethod(TInvoiceStatus.Paid, ProcessInvoicePaid); <span style="color: #000080; font-weight: bold;">end</span>; |
1 2 3 4 5 6 7 |
<span style="color: #000080; font-weight: bold;">function</span> TInvoiceProcessor .ProcessInvoiceNew: TProcessInvoiceProc; <span style="color: #000080; font-weight: bold;">begin</span> Result := <span style="color: #000080; font-weight: bold;">procedure</span>(<span style="color: #000080; font-weight: bold;">const</span> Invoice: TInvoice) <span style="color: #000080; font-weight: bold;">begin</span> ShowMessage(<span style="color: #0000ff;">'This is a new invoice'</span>); <span style="color: #000080; font-weight: bold;">end</span> <span style="color: #000080; font-weight: bold;">end</span>; |
A aplicação do Factory pattern é fácil e ocorre conforme o código abaixo:
1 2 3 4 5 6 7 8 |
<span style="color: #000080; font-weight: bold;">procedure</span> TInvoiceProcessor .ProcessInvoice(<span style="color: #000080; font-weight: bold;">const</span> Invoice: TInvoice); <span style="color: #000080; font-weight: bold;">begin</span> <span style="color: #000080; font-weight: bold;">if</span> FFactory.IsRegistered(Invoice.Status) <span style="color: #000080; font-weight: bold;">then</span> <span style="color: #000080; font-weight: bold;">begin</span> <span style="color: #000080; font-weight: bold;">var</span> Process := FFactory.GetInstance(Invoice.Status;) Process(Invoice); <span style="color: #000080; font-weight: bold;">end</span>; <span style="color: #000080; font-weight: bold;">end</span>; |
Contato