8 de setembro de 2009

Design Patterns com Delphi : Adapter

Com o avanço do uso de componentes na computação tem sido cada vez mais comum desenvolver programas que nada mais são que uma colagem de bibliotecas de terceiros. Além dos IDEs de ferramentas como Delphi, VB.NET e C# direcionarem o desenvolvimento de software por componentização, vem crescendo também a quantidade de desenvolvedores criando bibliotecas de software livre.

Muitos componentes, no entanto, vão se tornando obsoletos conforme evoluem os sistemas operacionais, as técnicas de programação e mesmo o hardware. A ABC71, por exemplo, passou bastante tempo usando BDE em suas aplicações para acessar banco de dados. Quando a Borland (hoje Embarcadero) descontinuou a evolução dessa biblioteca, tivemos que adotar outra solução para acesso aos dados.

O Design Pattern estrutural Adapter, às vezes também chamado de Wrapper, fornece uma solução bastante prática para esse tipo de problema, de modo que foi preciso alterar basicamente apenas um arquivo fonte para por nosso ERP Omega para funcionar com ADO no lugar do BDE. Veja abaixo o diagrama UML para a solução típica do Adapter.

Diagrama UML para Adapter
A solução típica é composta de 4 classes, sendo que a nomenclatura delas é a seguinte:
O Target é a classe que define a interface que o programa vai enxergar, isso é, quais são os nomes de métodos e propriedades que estarão disponíveis para o programa, independente de qual tecnologia será realmente utilizada. No diagrama anterior, a classe TWDBManager exerce esse papel.
O Adapter faz o meio de campo, isto é, implementa os métodos descritos pelo Target usando métodos e propriedades expostos pela classe que está sendo encapsulada (o Adaptee). No diagrama acima, esse papel cabe às classes TWBDEMan e TWADOMan, que adaptam o acesso respectivamente às funções do BDE e do ADO.
O Adaptee corresponde à classe que efetivamente realiza as tarefas que precisamos. Ela pode vir tanto de uma tecnologia específica dentro do mesmo ambiente de desenvolvimento (como é o caso do ADO e do BDE) quanto vir de uma biblioteca ou componente de terceiros.
A classe Client faz uso dos métodos expostos pelo Target para realizar as operações de que precisa. Ela não tem conhecimento de qual tecnologia ou biblioteca ou componente está sendo de fato usado. No exemplo, esse é o papel exercido pelo TWBusinessObj.

Qual das classes que implementam a interface do Target deve ser instanciada é uma decisão que pode ser resolvida pelo Pattern Factory Method, já que todas as soluções possíveis estão incluídas no programa e são conhecidas.

Em Delphi, a implementação do Adapter é resolvida através de herança onde a classe base (o Target) é abstrata:
type
TWDBManager = class
{ ... }
procedure Connect;virtual;abstract;
procedure BeginTrans;virtual;abstract;
procedure Commit;virtual;abstract;
procedure ExecSQL;virtual;abstract;
procedure OpenSQL;virtual;abstract;
end;

TWBDEMan = class(TWDBManager)
{ ... }
procedure Connect;override;
procedure BeginTrans;override;
procedure Commit;override;
procedure ExecSQL;override;
procedure OpenSQL;override;
end;

TWADOMan = class(TWDBManager)
{ ... }
procedure Connect;override;
procedure BeginTrans;override;
procedure Commit;override;
procedure ExecSQL;override;
procedure OpenSQL;override;
end;

O que a classe TWBusinessObj precisa conhecer é apenas a interface - todos os métodos necessários já estão definidos nela:
type
TWBusinessObj = class
{ ... }
_DBMan : TWDBManager;
procedure ExecTransaction;
end;

{ ... }

procedure TWBusinessObj.ExecTransaction;
begin
_DBMan.BeginTrans;
{ outras operações aqui }
_DBMan.Commit;
end;

Aqui, usei o padrão Adapter para substituir completamente uma tecnologia por outra que estava sendo descontinuada mas não é preciso que o cenário seja tão radical para poder aplicar esse padrão. Pode ser usado também em situações em que o usuário pode optar por uma tecnologia entre várias compatíveis. Por exemplo, numa aplicação de jogo pode-se optar por usar emulação de operações de vídeo ou submetê-las diretamente à placa de vídeo.

Mais Informações
Posts sobre Design Patterns

Nenhum comentário :

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.