descadastro
site NCE
 
 
Projeto Orientado a Objetos
 
artigos publicados

Organizando a Lógica de Domínio em Aplicações OO

 

Jonas Knopman, D.Sc.
Pesquisador NCE/UFRJ

   
 


1. Introdução
Em uma aplicação Orientada a Objetos (OO) a lógica da aplicação é distribuída por uma rede de objetos. Usualmente estes objetos residem em uma camada chamada de camada de domínio. Tradicionalmente, existem três formas principais de organizar os objetos na camada de domínio:
a) Roteiros de Transação: Toda a lógica de uma transação ou de um caso de uso é encapsulada em um único objeto que valida os dados, processa esses dados, faz consultas e atualiza o banco de dados, etc. Um problema em particular com os Roteiros de Transação é que qualquer código comum às transações tende a ser duplicado. Apesar de constituir uma arquitetura “pobre” para um sistema orientado a objetos, seu uso não deve ser desprezado em sistemas simples onde o tempo de desenvolvimento é um dado crítico.
b) Módulos Tabela: Neste modelo, cada tabela no banco de dados é representada por um objeto na camada de domínio. Este objeto encapsula todo o código SQL necessário para recuperar, inserir e atualizar dados da tabela. Cada módulo tabela é responsável por uma única tabela e não conhece a estrutura das demais tabelas. Seu uso deve ser considerado quando o modelo conceitual é muito parecido com o esquema do banco de dados. Um Módulo Tabela é uma solução simples para organizar a lógica do domínio, no entanto, você não pode usar várias das técnicas disponíveis para organizar a lógica de domínio em aplicações complexas tais como herança, estratégias e outros padrões OO.
c) Modelo de Domínio: Cada instância de um conceito no domínio da aplicação é representada por um objeto na camada de domínio. Assim, teríamos um objeto para cada aluno de uma universidade, um objeto para cada exemplar de uma biblioteca, etc. Quanto mais complexa a lógica de uma aplicação, maiores são os benefícios na utilização de um Modelo de Domínio. Diversas técnicas estão disponíveis que permitem lidar com lógica complexa de uma forma organizada [Gamma et al.]. Os inconvenientes no uso de um Modelo de Domínio vem da complexidade do uso e da complexidade da camada de dados.
Estudaremos neste artigo os dois modelos de maior complexidade: Módulos Tabela e Modelos de Domínio.

2. Camadas
A criação de camadas é uma das técnicas mais comuns que os projetistas usam para quebrar a complexidade de um sistema de software. Um exemplo conhecido são as redes de computadores: o serviço FTP consiste em uma camada sobre TCP o qual, por sua vez, é uma camada sobre IP, que por sua vez está sobre a ethernet.
Neste esquema, a camada em um nível mais alto usa os serviços disponibilizados pela camada imediatamente inferior, mas esta ignora a existência da camada mais alta. Além disso, cada camada normalmente esconde suas camadas mais baixas das camadas acima (Figura 1). Assim, a camada 3 usa os serviços da camada 2 a qual usa os serviços da camada 1, mas a camada 3 ignora a existência da camada 1.




Dividir um sistema em camadas tem uma série de benefícios importantes:
· Você pode compreender uma única camada como um todo coerente sem saber muito sobre as outras camadas. Por exemplo, você pode compreender como construir um serviço FTP sobre TCP sem conhecer os detalhes de como funciona o protocolo ethernet.
· Você pode substituir uma camada por uma implementação alternativa, desde que ela ofereça os mesmos serviços em sua interface.
· Você minimiza as dependências entre as camadas. Se houver alterações na interface da camada 1, estão alterações serão sentidas pela camada 2, mas não afetarão a camada 3.
· Uma mesma camada pode ser usada por muitos serviços diferentes na camada imediatamente acima. Usando ainda o exemplo das redes de computadores, TCP/IP é usado por FTP, telnet, SSH e HTTP.

3. A Evolução das Camadas

A noção de camadas se tornou mais visível nos anos 90 com o advento dos sistemas cliente-servidor. Estes eram sistemas em duas camadas: O cliente mantinha a interface com o usuário e a lógica da aplicação enquanto que o servidor, normalmente, era um banco de dados relacional. Ferramentas comuns para o lado cliente eram, por exemplo, VB e Delphi. Estas ferramentas tornavam particularmente fácil criar aplicações que faziam uso intensivo de dados, na medida que elas disponibilizavam componentes visuais que trabalhavam com SQL. Assim, você podia criar uma tela arrastando controles para uma área de desenho e, então, usando páginas de propriedades, conectar os controles ao banco de dados.
Se a aplicação tivesse somente de exibir e fazer atualizações simples em dados relacionais, estes sistemas cliente-servidor funcionavam bem. O problema surgia com a lógica de domínio complexa: regras de negócio, validações, cálculos, e assim por diante. Normalmente, as pessoas escreviam essa lógica no cliente (clientes gordos), embutindo-a diretamente nas telas da interface com o usuário, mas isso era deselegante. À medida que a lógica do domínio crescia em complexidade, tornava-se muito difícil trabalhar com este código:
· embutir lógica nas telas facilitava a duplicação de código, o que significava que alterações simples podiam resultar em buscas de código semelhante em muitas telas.
· a existência de lógica de domínio nas telas dificultava as alterações na interface com o usuário (por exemplo, a migração de uma interface cliente do tipo desktop para a web).
Uma alternativa era colocar a lógica de domínio no banco de dados na forma de procedimentos armazenados (clientes magros). No entanto, os procedimentos armazenados usavam linguagem proprietária o que eliminava a possibilidade de migração entre diferentes fornecedores de SGBDs.
A resposta para o problema da lógica de domínio veio então da comunidade OO: migrar para um sistema em três camadas. Nesta abordagem você tem uma camada de apresentação para a interface com o usuário, uma camada de domínio para a lógica de domínio e uma camada de acesso a dados. Desta maneira você pode tirar toda a complexa lógica de domínio da interface com o usuário e colocá-la em uma camada onde é possível estruturá-la apropriadamente utilizando objetos.




 
avançar >>
         
 
    página principal
 
Núcleo de Computação Eletrônica
Universidade Federal do Rio de Janeiro
Prédio do Centro de Ciências Matemáticas e da Natureza Bloco C
Caixa Postal: 2324 - CEP: 20.010-974
Cidade Universitária - Ilha do Fundão, Rio de Janeiro - RJ Tel: 2598-3333