Orientação a Aspectos com Delphi

O artigo apresenta um novo paradigma avançado no desenvolvimento, a programação orientada a aspectos.

Fique por dentro
Neste artigo aprenderemos como utilizar a orientação a aspectos em Delphi. Veremos todos os conceitos teóricos necessários para o perfeito entendimento desse paradigma de programação relativamente novo, e como ele vem complementar e aprimorar a programação orientada a objetos.

Faremos um estudo completo de uma classe ainda pouco conhecida dos desenvolvedores Delphi, que é a TVirtualMethodInterceptor que permite a injeção de métodos antes, depois e ao ocorrer exceções em qualquer método virtual de qualquer classe que desejarmos, permitindo assim implementar um Framework básico de orientação a aspectos em Delphi.

Serão utilizados vários recursos avançados da linguagem como Métodos Anônimos, Generics, Reflection e RTTI.

O Delphi, desde o seu surgimento, se caracterizou por ser uma excelente ferramenta RAD (Rapid Application Development), graças a poderosos componentes presentes na VCL, como TClientDataSet, TDataSetProvider e TDataSource.

Porém, no desenvolvimento de sistemas de grande, porte onde existem grandes equipes de desenvolvimento, não podemos ficar limitados a esses componentes e sim, utilizar o desenvolvimento Orientado a Objetos, aproveitando que o Delphi oferece todos os pré-requisitos que uma linguagem que suporta este paradigma deve ter (abstração, encapsulamento, herança e polimorfismo) e utilizando boas práticas de programação, princípios da orientação a objetos e padrões de projetos.

Infelizmente, o Delphi deixa um pouco a desejar no que diz respeito a existência de sólidos Frameworks que auxiliam o desenvolvedor a implementar sistemas Orientados a Objetos.

Já no que diz respeito ao compilador, não há o que reclamar, já que o Delphi no decorrer dos anos, principalmente após a aquisição da ferramenta pela Embarcadero, vem a cada versão trazendo novos recursos que possibilitam ao desenvolvedor maneiras de contornar a falta da existência de alguns frameworks prontos para desenvolvermos sistemas puramente Orientado a Objetos.

Mas isso por outro lado traz um benefício, já que os desenvolvedores têm que conhecer a fundo a linguagem e desenvolver suas próprias classes e Frameworks básicos que possam auxiliar nas atividades do dia-a-dia. Quem conhece os recursos avançados da linguagem como Métodos Anônimos, Generics, Custom Attributes e RTTI, consegue driblar esta falta de Frameworks através da criatividade.

Problemas da orientação a objetos

Todo software que segue o paradigma Orientado a Objetos possui uma parte de seu código que é alheio à implementação de comportamento do objeto.

Estes códigos são todos aqueles que servem para o desenvolvimento de funcionalidades secundárias, e que se encontram espalhados por toda a aplicação (crosscutting concern).

Alguns exemplos destas funcionalidades secundárias são Controle de Permissões, Manipulação de Exceções, Log de dados, Controle de Concorrência.

Mesmo que estas funcionalidades secundárias dos sistemas sejam implementadas em objetos, as chamadas aos métodos destas classes ficarão espalhadas por todo o sistema, caracterizando um auto acoplamento entre as partes básicas e secundárias dos sistemas.

A Programação Orientada a Aspectos surge para encapsular e modularizar esse código, e pode ser encarada como uma extensão da Programação Orientada a Objetos.

Nela, encapsulamos uma determinada funcionalidade secundária em uma nova unidade: um aspecto. Esta funcionalidade é implementada de forma que garantimos que a mesma será aplicada nos instantes corretos da execução de um programa, sem que outros objetos envolvidos sejam afetados, de forma totalmente transparente.

Vale lembrar que a Orientação a Aspectos não pode existir de forma isolada, ela foi criada para trabalhar em conjunto com a Orientação a Objetos, que ao contrário da primeira, pode existir de forma isolada.

A Orientação a Aspectos nos diz que toda a funcionalidade que não se refira a execução de regras de negócio, não deve estar presente na implementação do método e que todas as funcionalidades secundárias devem ser injetadas e executadas em outro lugar.

Observe, por exemplo, a Listagem 1. Quase toda sua implementação acaba ferindo o Princípio da Responsabilidade Única (BOX 1), que é um dos pilares da Orientação a Objetos. Segundo a Orientação a Aspectos, a única linha que deveria existir no método ExecutaOperacao é a linha 6, que faz a execução das regras de negócio.

Listagem 1. Exemplo da mistura de interesses dentro de um mesmo método 01 procedure ExecutaOperacao; 02 begin 03 // Verifica Autorizacao; Funcionalidade Secundária 04 // Inicia Transacao; Funcionalidade Secundária 05 06 // Executa Regras De Negocio; Funcionalidade Principal 07 08 // Finaliza Transação Funcionalidade Secundária 09 // Grava Logs de Execução Funcionalidade Secundária 10 end;

BOX 1. Princípio da Responsabilidade Única

O princípio da Responsabilidade Única de classes indica que cada classe deve ter uma única responsabilidade, que deve estar totalmente encapsulada por ela. Assim, todos os seus métodos devem agir em conjunto para executar sua funcionalidade, desta forma, ela possui uma única razão ou motivo para ser alterada.

Isto não significa que uma classe deva ter somente um método, mas que tenha métodos que juntos cheguem a um determinado objetivo comum. Uma classe poderá ser responsável por uma funcionalidade que pode precisar de cinco métodos para resolver sua tarefa. Classes assim propagam menos mudanças para o restante do sistema no caso da necessidade de alteração."

[...] continue lendo...

Artigos relacionados