|
Usuários |
|
76 Usuários Online
|
|
[Artigos]
[Intermediário] - Chain od Reponsability -Padrões de Projeto no Delphi Parte III |
Publicado por rboaro : Quinta, Setembro 26, 2013 - 07:08 GMT-3 (252 leituras)
comentar Enviar para um amigo Versão para impressão
|
Nosso objetivo inicial foi desenvolver um Algorítmo genérico que implementasse o Padrão Chain of Responsability . Por ser genérico , as classes envolvidas tem acoplamento fraco entre si e podem ser trocadas sem prejuízo à sua funcionalidade . Para isto no artigo anterior dêmos inicio a criação das classes
TMoeda … Classe Base que implementa a Classe TWBusinessObj
TCinco_Centavos , TDez_Centavos , TVinteCinco_Centavos especialização da classe TMoedas
IModelo uma interface que aparetemente é um buraco negro
TDocumento_Moeda implementa a classe TInterfaced_Objecto e a Interface IMoeda
Vamos então partir para a definição da classe TWBussinessObj , que é o coração de todas as classes Pai que necessitam implementar o Modelo . Só recaptulando , temos a necessidade baseado em alguns critérios definidos (Peso,Diametro,Espessura) executar um método , e através de uma Cadeia de Responsabilidade , nosso Algoritmo de maneira Orientada a Objeto vai perguntar para os Objetos (TCinco_Centavos , TDez_Centavos , TVinteCinco_Centavos , TTantosOutros_Centavos etc… ) é sua ossada retornar o Valor ??? E Cada Objeto vai delegando o Poder de modo hierárquico ao Seu sucessor para que este decida o que é para fazer , se é responder a requisição ou “cutucar” o seu sucessor . Esta mágica se dá através da chamada
//para nos o importante no momento é o método RequisitaAprovacao
function TMoedas.RequisitaAprovacao(aDoc: IDocumento): TValue;
begin
with TDocumento_Moeda(adoc) do
if (Espessura = self.FEspessura)and
(Peso = self.FPeso)and
(Diametro = self.FDiametro) then
result:=FValor
else
if Assigned(sucessor) then
result:=sucessor.RequisitaAprovacao(aDoc);
end;
Antes de mais nada vamos definir a Interfaces IBusiness que será o contrato a ser respeitado pela classe TWBusinessObj
unit uIBusiness;
interface
uses
rtti,uIDocumento;
type
IBusiness = Interface
['{55177B0A-EC12-47AE-A1EA-A4362B57834D}']
procedure SetSucessor(aSucessor:IBusiness);
function RequisitaAprovacao(aDoc:IDocumento):TValue;
procedure SetFdocumento(Value:IDocumento);
function GetFDocumento:Idocumento;
property Documento:Idocumento read GetFDocumento Write SetFDocumento;
End;
implementation
end.
Sem mais delongas vamos a implementação da classe TWBussinessObj
unit uTWBusinessObj;
interface
uses
Rtti,uIBusiness, uIDocumento, uDocumentoMoney;
Type
TWBusinessObj = class(TInterfacedObject,IBusiness)
protected
FDocumento:IDocumento;
sucessor:IBusiness;
procedure SetFdocumento(Value:IDocumento);
function GetFDocumento:Idocumento;
public
procedure SetSucessor(aSucessor:IBusiness); virtual;
function RequisitaAprovacao(aDoc:IDocumento):TValue;virtual;abstract;
property Documento:Idocumento read GetFDocumento Write SetFDocumento;
end;
implementation
function TWBusinessObj.GetFDocumento: Idocumento;
begin
result:=FDocumento;
end;
procedure TWBusinessObj.SetFdocumento(Value: IDocumento);
begin
FDocumento:=Value;
end;
procedure TWBusinessObj.SetSucessor(aSucessor:IBusiness);
begin
Self.sucessor:=aSucessor;
end;
Perceba que a classe TWBussinessObj praticamente é a materialização da Interface IBusiness
Quando a gente espera algo divino , espetacular , majestoso , e vem algo relativamente simples passamos a entender que POO existe exatamente para sermos simples . O que tem nesta classes TWBusinessObj que dá a ela a grandeza devida , a não ser implementar uma Interface (IBusiness) e os seguintes métodos
dois deles relacionados a property Document (getFDocumento , SetFDocumento )
uma funçãoRequisitaAprovacao marcada como Virtual ; abstract e devera ser implementada nas classes Filhas . TMoedas = class (TWBusinessObj)
Um quarto método , SetSucessor(aSucessor:IBusiness); este sim é novidade para nos e vamos falar dele .
procedure TWBusinessObj.SetSucessor(aSucessor:IBusiness);
begin
Self.sucessor:=aSucessor;
end;
O método diz que o objeto sabe quem é o seu Sucessor … E para que o objeto precisa saber quem é o seu sucessor ??? Ora , para que o sucessor responda a requisição quando não for do objeto self a responsabilidade de ter que faze-lo . Lembra do método RequisitaAprovacao ?? Então neste cenário o sucessor de TCinco_Centavos será TDez_Centavos e de TDez_Centavos será TVinteCinco_centavos e assim a banda toca e assim a banda segue.
Uma pergunta inerente neste momento é como fazer com que os objetos conheçam o seu sucessores . ( A necessidade de ter que conhece-los a esta altura do campeonato não se discute ) , mas o que faz coçar a cabeça é como Fazer para que um Objeto TCinco_Centavos saiba que seu sucessor será TDez_Centavos ? Imagine o cenário
var
cinco_Centavos:TCinco_Centavos;
Dez_Centavos:TDez_Centavos;
......
begin
cinco_Centavos.Sucessor:=Dez_Centavos;
end;
O cenário acima não é para se imaginar . Argssss dá calafrio . E jogar por terra tudo que estamos fazendo até agora … Mas como que os objetos saberão quem é o seu sucessor sem ter que conhece-los ?? Para isto vou criar mais uma Interface e prometo a voces que será a última
unit uIChain_Of_Responsability;
interface
uses
Rtti,uIDocumento, uIBusiness;
type
IChain_Of_Resposability = Interface
['{BBBE5F24-4B71-4195-8524-AAD31F13B5D1}']
procedure configuraObjetos;
function ExecuteDocumento(aDoc:IDocumento):Tvalue;
function ConfigureDocumento(aListaSucessores:Array of IBusiness;aDoc:IDocumento):TValue;
function IsImplementDocumento(aBussiness:IBusiness;aDoc:Idocumento):Boolean;
End;
implementation
end.
Esta interface promove os seguintes contratos:
procedure configuraObjetos;
function ExecuteDocumento(aDoc:IDocumento):Tvalue;
function ConfigureDocumento(aListaSucessores:Array of IBusiness;aDoc:IDocumento):TValue;
function IsImplementDocumento(aBussiness:IBusiness;aDoc:Idocumento):Boolean;
O próximo passo será definir a classe TChain_Of_Resposability que consumira a interface IChain_Of_Resposability , mas faremos isto no próximo artigo onde finalmente finalizaremos este assunto . Quero deixar anotado que ainda não respondemos a questão de como os objetos sabem que é o seu sucessor e qual a finalidade desses métodos definidos nesta classe . No mais a pergunta de porque a necessidade de definir tantas classes ( vamos contar … )
TMoedas >>> TCinco_Centavos , TDez_Centavos , TVinteCinco_Centavos . Esta classes não fazem parte do Modelo e estão apenas usufruindo do mesmo ,portanto não devem ser contadas . servem apenas como exemplo e poderá ser qualquer outra
TDocumento_Moeda = class(TInterfacedObject,IDocumento) . Tb não faz parte do Modelo esta apenas fazendo a ponte entre a classe TMoedas e o Modelo
Essas classes acima não são minhas , estão aqui para exemplificar o Modelo elas poderão ser qualquer outras classes seguindo a sua abstração . Vamos voltar no cápituloI deste artigo
Na abstração que fizemos no processo de Sistema de Recebimento de uma concessionária teriamos as classes
TRecebimentos >>> TBalcao , TCaixa , TGerente , TBalcao e por analogia
TDocumento_Recebimento = class(TInterfacedObject,IDocumento)
O que muda entre uma classe e outra será o que deve ser retornado e o que deve ser Requisitado … No caso das Moedas seria o (diametro , peso , espessura ) , e retornara o Valor , no caso do Recebimento seria o Valor da Compra e o Retorno seria a aprovação deste Recebimento ( se é pelo objeto Balcao , se é pelo Caixa , se é pelo gerente ou se é pela Agência )
Estou entrando neste mérito para que percebam que a quantidade de entidades envolvidas no Modelo são apenas quatro .. Esta dando uma impressão de complexibilidade o que não é Verdade
IBusiness
TWBussinesObj
IChain_Of_Resposability
TChain_Of_Resposability
Através destas Entidades estaremos aptos a responder Requisições de quaisquer classes .. TMoedas , TRecebimentos , TCompras (ArtigoI) , TSuas_Classes_Amigo_Eleitor etc… O que torna o artigo , como eu disse desde o inicio , Expánsivel , Reutilizável , com Baixo Acoplamento e reafirmo por não ter visto nada em Delphi neste sentido me deu ânimo a escreve-lo e tentar fazer-me por entendido
No momento vou ficando por aqui pela sua atenção meu muito Obrigado …
Link Original do Artigo:
http://marcosalles.wordpress.com/2012/03/10/chain-of-responsability-cadeia-de-responsabilidades-padrao-de-projeto-no-delphi-design-patterns-parte-iii/
|
|
Comentários | |
| | Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos. |
|
|
Edição 112 |
|
|
50 Programas Fontes |
|
|
Produtos |
|
|