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

Codinome
Senha
Salvar informações

 Esqueci minha senha
 Novo Cadastro

  Usuários
40 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 IV
Publicado por rboaro : Sexta, Setembro 27, 2013 - 05:07 GMT-3 (441 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 O último passo deste livro ( não por minha culpa , ja disse antes que o modelo só requer quatro Entidades – IBusiness ; TWBussinesObj ; IChain_Of_Resposability ; TChain_Of_Resposability ) é implementar a classe TChain_Of_Resposability.
unit uTChain_Of_Responsability;

interface

uses
uIChain_Of_Responsability;

var
ChainOfResposability:IChain_Of_Resposability;

implementation

uses
Rtti,TypInfo,generics.collections,uIBusiness, uIDocumento,uTWBusinessObj,SysUtils;

Type
TBussinesOfDocumentNotImplement = Class (Exception);

TBussinesOfDocumentNill = Class (Exception);

TChain_Of_Resposability = class (TInterfacedObject,IChain_Of_Resposability)
private
FBusiness:TList<IBusiness>;
procedure configuraObjetos;
function ExecuteDocumento(aDoc:IDocumento):Tvalue;
function IsImplementDocumento(aBussiness:IBusiness;aDoc:Idocumento):boolean;
constructor create;reintroduce;
class function getInstance:TChain_Of_Resposability;
destructor Destroy;override;
public
function ConfigureDocumento(aListaSucessores:Array of IBusiness;aDoc:IDocumento):Tvalue;
end;

procedure TChain_Of_Resposability.configuraObjetos;
var
i:integer;
begin
for i:=0 to pred(FBusiness.Count-1) do
with IBusiness(FBusiness.Items[i]) do
SetSucessor(IBusiness(FBusiness.Items[i+1]));
end;

constructor TChain_Of_Resposability.create;
var
I: Integer;
begin
FBusiness:=TList<IBusiness>.create;
end;

destructor TChain_Of_Resposability.Destroy;
begin
FBusiness.Free;
inherited;
end;

function TChain_Of_Resposability.ExecuteDocumento(aDoc:IDocumento):Tvalue;
begin
result:= FBusiness[0].RequisitaAprovacao(aDoc);
end;

class function TChain_Of_Resposability.getInstance: TChain_Of_Resposability;
begin
if not Assigned(ChainOfResposability) then
begin
ChainOfResposability:=TChain_Of_Resposability.Create;
end;
result:=TChain_Of_Resposability(ChainOfResposability);
end;

function TChain_Of_Resposability.IsImplementDocumento(
aBussiness:IBusiness;aDoc:Idocumento): boolean;
begin
try
result:=true;
if not Assigned(aBussiness.Documento) then
raise TBussinesOfDocumentNill.Create(
'O Objeto que implementa a Classe : '+
TObject(aBussiness).ClassName+sLineBreak+
' não possui nenhum documento Vinculado');

if TObject(aBussiness.Documento).ClassType <> TObject(aDoc).ClassType then
raise TBussinesOfDocumentNotImplement.Create(
'O Documento : '+ TObject(aDoc).ClassName+
' Não é um Documento'+sLineBreak+
'Válido para os objetos que implementam a Classe '+
TObject(aBussiness).ClassName);
result:=true;
except
raise;
end;
end;

function TChain_Of_Resposability.ConfigureDocumento(
aListaSucessores:Array of IBusiness;aDoc:IDocumento):TValue;
var
i:integer;
begin
try
FBusiness.Clear;
for I := Low(aListaSucessores) to High(aListaSucessores) do
begin
if IsImplementDocumento(aListaSucessores[i],aDoc) then
FBusiness.Add(aListaSucessores[i]);
end;
self.configuraObjetos;
result:=self.ExecuteDocumento(aDoc);
except
on e:Exception do
raise Exception.Create(e.message);
end;
end;

initialization

ChainOfResposability:= TChain_Of_Resposability.getInstance;

end.

em primeiro lugar perceba que nos implementamos um Padrão Factory dentro desta classe. De modo que so uma instâcia ChainOfResposability será para toda a aplicação. mas se só Temos uma única instância , como ela pode servir para TMoedas ,TRecebimentos , TCompras , TSuas_Classes_Amigo_Eleitor ??? Perceba que esta classe disponibiliza o método ConfigureDocumento e neste método passaremos um Array de objetos para o modelo . Assim se passarmos os objetos [objCinco_Centavos , objDez_Centavos , objVinteCinco_Centavos] nosso documento será TMoeda ..Com isto desaclopamos o Modelo para qualquer Tipo. Se misturamos os objetos com o Modelo uma exceção sera lançada . vejamos a definição do método e sua utilização

function TChain_Of_Resposability.ConfigureDocumento(
aListaSucessores:Array of IBusiness;aDoc:IDocumento):TValue;

Passamos a Lista emforma de Array de IBusiness e o Tipo de Documento . TDocumeto_Moeda , TDocumento_Recebimentos , TDocumento_Compras , TDocumento_SeuAmigoEleitor . Na execução deste método (que é o unico Público desta Classe) , verificaremos se a lista de os objetos passados , são compativeis com o tipo de Documento. Caso não seje uma exceção será lançada . Por isto nos dentro desta classe definimos alguns tipos especiais de Exceções : TBussinesOfDocumentNotImplement e TBussinesOfDocumentNill

agora ja estamos no ponto de respondermos uma pergunta que finalizou o ArtigoIII desta Série .

“Mas como que os objetos saberão quem é o seu sucessor sem ter que conhece-los ??”

O método ConfigureDocumento explica tudo , vamos ver sua implementação e analiza-lo:

function TChain_Of_Resposability.ConfigureDocumento(
aListaSucessores:Array of IBusiness;aDoc:IDocumento):TValue;
var
i:integer;
begin
try
//limpando a lista interna
FBusiness.Clear;
//varrendo a lista de objetos passado como parãmetros
for I := Low(aListaSucessores) to High(aListaSucessores) do
begin
//verificando se os Objetos implementam o Documento
if IsImplementDocumento(aListaSucessores[i],aDoc) then
//caso Implemente adicionamos estes objetos em ordem na lista
FBusiness.Add(aListaSucessores[i]);
end;
//configuramos os sucessoreso dos objetos
self.configuraObjetos;
//excutamos a Requisicao
result:=self.ExecuteDocumento(aDoc);
except
on e:Exception do
raise Exception.Create(e.message);
end;
end;

A proxima etápa e o método ConfiguraObjetos

procedure TChain_Of_Resposability.configuraObjetos;
var
i:integer;
begin
//varre a Lista Interna de Objetos atribuindo o Sucessor
//perceba que varremos a lista de Zero ate count-2 .. Note a função Pred
for i:=0 to pred(FBusiness.Count-1) do
with IBusiness(FBusiness.Items[i]) do
//atribuimos o secessor de i sendo o objeto i+1
SetSucessor(IBusiness(FBusiness.Items[i+1]));
end;

Ja estamos no final , praticamente tudo que a meu ver era importante , acho que foi dito e repetido algumas vezes , e nos ainda não fizemos um exemplo prático com esta teoria . então mãos a obra

Em um formulario coloque um Button três ComboBox denominados (cbEspessura, cbPeso , CbDiametro) e em seus Items coloque os valores estipulados para Espesura Peso , diametro respectivamente

object cbEspessura: TComboBox
..................
Items.Strings = (
end

object cbPeso: TComboBox
.................................
Items.Strings = (
end
object cbDiametro: TComboBox
.........................
Items.Strings = (
end


e de uses as respctivas Unidades

uses
uTChain_Of_Responsability, uIDocumento, uDocumentoMoedas, uCinco_Centavos, uDez_Centavos, uVinteCinco_Centavos;

E para utilizar em no Button no seu evento onclick escrevamos

procedure TSeuForm.btnValorMoedaClick(Sender: TObject);
var
//definindo o Objeto
objMoeda:IDocumento;
begin
//isntanciando o Modelo do Objeto (Pode ser qualquer classe Tdocumento_SuaClasseAmigoEleitor
objMoeda:=TDocumento_Moeda.Create;
//fazendo o Type Cast para recuperar as informações da Classe TDocumento_Moeda
with TDocumento_Moeda(objMoeda) do
begin
//defininoo o que chamamos ate o momento de Regras de Validação
Espessura:= strtoFloatDef(cbEspessura.Items.Strings[cbEspessura.ItemIndex],0);
Peso:=strtoFloatDef(cbPeso.Items.Strings[cbPeso.ItemIndex],0);
diametro:=strtoFloatDef(cbdiametro.Items.Strings[cbDiametro.ItemIndex],0);
end;
//Executamos o Unico método ConfigureDocumento público da classe TChainOfResposability
//Aqui representado pelo Objeto Global ChainOfResposability e passamos o array de Objetos
//bem como o Documento
showmessage(FloatToStr(ChainOfResposability.ConfigureDocumento(
[Cinco_Centavos,Dez_Centavos,VinteCinco_Centavos],objMoeda).AsExtended));
end;


O resultado será recuperado em forma de Mensagem ( só para efeito didático ) . Quero deixar claro que podemos passar qualquer lista de Objetos (não necessariamente objetos do tipo TMoedas ). O método não esta Vinculado a nenhuma classe específica e você pode seguir este passos para utilizar o Padrão para objetos do Tipo TsuaClasseAmigoeleitor . lembramos que será necessário um Documento que a implemente

Quero Agradecer esta Longa paciência , quero deixar meus contatos , e acolher qualquer reclamação , sugestão , ou Critica e pedir por gentileza , respeitando os direitos autorais que por alguma razão esta artigo venha sofrer qualquer vinculação na mídia , que se faça por cordialidade e gentileza menção ao seu verdadeiro autor. Por fim quero deixar mais uma vez comentado e documentado que esta não é a única solução e se trata de uma abstração à cerca da Implementação deste Padrão , bem como afirmar que eu não sou a solução só faço parte dos problemas . Meu muito obrigado um abraço amigo e até a próxima

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-iiii/


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