|
Usuários |
|
40 Usuários Online
|
|
[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)
comentar Enviar para um amigo Versão para impressão
|
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 pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos. |
|
|
Edição 112 |
|
|
50 Programas Fontes |
|
|
Produtos |
|
|