Page 37 - Revista_60.pub
P. 37
A PROGRAMAR
Classes de infraestrutura: a classe Using
E m Object Oriented Programming (OOP), classes utilitá- A forma típica (e bastante eficaz) de resolver isto é
rias são de evitar. O mesmo se pode dizer de métodos estáti- colocar o código dentro de um bloco try...finally
cos.
Um bom design OOP deve procurar que cada objeto represen- (* Método 2 *)
te uma entidade real, uma parte do todo que é o software, com var
uma responsabilidade bem definida e uma vida útil determina- Foo: TFoo;
da pelo exercício dessa responsabilidade, e não mais do que begin
isso. Uma classe utilitária ou um método estático acabam por ir Foo := TFoo.Create;
contra o exercício desse objetivo. try
// Do something
No entanto, podemos separar o nosso design em duas finally
partes distintas: domínio do problema e infraestrutura. Foo.Free;
end;
Por domínio, refiro-me ao conjunto de código relativo end;
especificamente ao projeto em que estamos a trabalhar. User
Interface, regras de negócio, etc. são da alçada do domínio. Já Desta forma, havendo o levantamento de uma exce-
na infraestrutura, podemos ter classes ou métodos de apoio, ção, o Free será ainda assim executado, e está resolvido o
que não representem claramente uma entidade, mas que não segundo problema da primeira forma.
estão relacionadas com o projeto em si, mas sim com caracte-
rísticas específicas da linguagem de programação que estiver- Também o primeiro problema fica atenuado, pois a
mos a usar. estrutura visual do bloco try...finally ajuda a chamar a aten-
ção para o local onde o Free deve existir. Não elimina o pro-
Neste artigo iremos ver um exemplo de uma classe de blema, mas ajuda.
infraestrutura: A classe Using
A classe Using não trás consigo o santo graal da
Sempre que instanciamos um objeto em Delphi, o com- programação. O que ela nos dá é uma forma diferente de
pilador atribui na heap memória suficiente para esse objeto. executar o método 2. No entanto, é um método que garante
Cabe ao programador, na maioria dos casos, encarregar-se de que o Free será sempre chamado no fim do código, pelo
libertar essa memória. Este seria o método tradicional de o simples motivo que o programador deixa de ter de o fazer, e
fazer:
por esse motivo, nunca se poderá esquecer dele.
(* Método 1 *) A sua utilização seria da seguinte forma:
var
Foo: TFoo; (* Método 3 *)
begin begin
Foo := TFoo.Create; Using.New<TFoo>(
// Do something procedure (Foo: TFoo)
begin
Foo.Free; // Do something
end; end
);
end;
Esta é uma forma típica de usar a classe TFoo. Tem, no entan-
to, dois problemas sérios: Como se pode ver, em lado nenhum o programador
precisou chamar o método Free. No entanto, ele está a ser
Facilmente o programador se esquece de chamar o executado. Além disso, não foi sequer necessário instanciar
método Free. Quando entre a instanciação da classe e a classe TFoo. Também isso é tratado, neste caso, pela
a sua destruição só há uma linha, como no exemplo, é classe Using. E um pequeno brinde extra é que nem mesmo
fácil notar a falta do Free num caso de esquecimento. a declaração da variável foi necessária, visto que a classe
Mas se houverem mais linhas pelo meio, facilmente será instanciada diretamente no parâmetro do método anóni-
passa despercebida a sua ausência. O resultado são mo recebido pela classe Using.
vazamentos de memória (memory leaks).
É possível verificar que esta alteração não irá afetar
Se for levantada uma exceção após a criação e antes em nada o resultado final do projeto. Conseguiríamos exata-
da destruição da classe, o Free nunca chega a ser cha- mente o mesmo resultado final com o método 2. É só uma
mado, e mais uma vez, irão existir vazamentos de me- forma diferente de dar a volta a uma questão específica da
mória. linguagem, e é por isso que a este tipo de classes se chama
de infraestrutura.
37