Clique para saber mais...
  Home     Download     Produtos / Cursos     Revista     Vídeo Aulas     Fórum     Contato   Clique aqui para logar | 15 de Novembro de 2025
  Login

Codinome
Senha
Salvar informações

 Esqueci minha senha
 Novo Cadastro

  Usuários
76 Usuários Online

  Revista ActiveDelphi
 Assine Já!
 Edições
 Sobre a Revista

  Conteúdo
 Apostilas
 Artigos
 Componentes
 Dicas
 News
 Programas / Exemplos
 Vídeo Aulas

  Serviços
 Active News
 Fórum
 Produtos / Cursos

  Outros
 Colunistas
 Contato
 Top 10

  Publicidade

  [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)
Comentários comentar   Enviar esta notícia a um amigo Enviar para um amigo   Versão para Impressão Versão para impressão
Marcos Salles 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
   Ordem:  
Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos.
  Edição 112

Revista ActiveDelphi

  50 Programas Fontes


  Produtos

Conheça Nossos Produtos

Copyright© 2001-2016 – Active Delphi – Todos os direitos reservados