Capítulo 4

No capítulo anterior dessa série discutimos sobre a criação da camada DAO. Geramos as classes e interfaces, além de preparar um DAOFactory que é o caminho por onde serão feitos acessos às funcionalidades dos DAOs. Vimos também como utilizar uma classe abstrata BaseDAO que pode facilitar o uso dos recursos do NHibernate.

Neste capítulo vamos discutir sobre a camada de regras de negócio (BO). Vamos acessar os DAOs através de um DAOAccess e criar um BOFactory para que a camada de apresentação possa utilizar este caminho para fazer acessos ou requisições às regras de negócio.

Como o próprio nome já diz a camada de regras de negócio define as regras ou comportamentos que a aplicação terá durante o processamento de requisições oriundas da camada de apresentação. Esta camada pode ser formada por uma ou várias classes que serão responsáveis por processar informações. Não acho interessante criar uma única classe para controlar todas as regras de negócio da aplicação. Procuro agrupar em classes, separando as operações relacionadas. Dessa forma consigo ter melhor visão dos módulos da aplicação.

Mas o que tem numa classe de negócio?! Como sabemos uma classe é formada basicamente por métodos e propriedades. Os métodos das classes da camada de negócio irão ser chamados na camada de apresentação para realizar as operações de negócio. Os parâmetros dos métodos servirão de base para determinar algum comportamento do método. Vamos conhecer algumas métodos que podemos colocar numa classe de negócio:

  1. Inclusão e alteração de dados. Esses métodos são os mais comuns em qualquer aplicação que utilize banco de dados. Eles serão chamados pela camada de apresentação para realizar a devida operação no banco de dados (através dos DAOs); Nesses métodos podemos encontrar procedimentos comuns em operações de inclusões e alterações, por exemplo:
    • validação de permissões de usuário;
    • validação de campos;
    • verificações de relacionamentos entre tabelas do banco;
    • verificações de violação de índices ou chaves;
    • abertura e fechamento de transações;
    • inserções e/ou alterações em tabelas;
    • outros processos durante a operação;
    • Processamentos referentes ao domínio da aplicação.
  2. Exclusões. Esses métodos realizam operações de exclusão de dados do banco. Internamente também possui procedimentos comuns ao processo:
    • validação de permissões;
    • verificação de violação de relacionamentos;
    • verificações de violação de índices ou chaves;
    • abertura e fechamento de transações;
    • eliminações de dados em tabelas
    • outros processos durante a operação.
  3. Seleções de linhas da tabela. Esses métodos vão dar suporte a consultas e listagens que a camada de apresentação possa necessitar e também para outros objetos de negócio:
    • Seleção de uma linha da tabela por chave primária ou índice único;
    • Listagem de registros das tabelas controlada ou não por filtro;

Acredito que, no mínimo, todas as aplicações realizam alguma ou todas as operações e sub-processos citados acima. Já que esses processos são comuns a maioria das aplicações em camadas e que fazem acesso a banco de dados, seria interessante que pudessemos automatizar a criação desses métodos. Foi exatamente o que eu fiz criando o RSClass – Gerador de Classes. Vamos utilizá-lo para gerar as classes da nossa camada de negócio.

Claro que, obedecendo a hierarquia em camadas, as classes de negócio fazem chamadas às classes DAOs. E essas chamadas são feitas atravéz do DAOFactory por um DAOAccess. Parece complicado mas não é. Apenas estou determinando que nenhuma classe DAO seja instanciada com new diretamente na camada de negócio. Quem terá essa responsabilidade fazer solicitações a camada DAO será o DAOAccess e quem irá responder a essas solicitações de instanciamento dos objetos é o DAOFactory. Como voce deve ter notado o DAOAccess conversa apenas com o DAOFactory. O DAOAccess está na camada de negócio. Sempre que uma classe precisar conversar com um DAO essa classe é acionada e ela, por sua vez, aciona a classe DAOFactory presente na cadama inferior que, por sua vez, aciona o DAO solicitado. Sempre dessa forma.

O processo de criação dos BOs e das interfaces usando o RSClass – Gerador de Classes é similar ao que fizemos na criação dos DAOs e suas interfaces. Inclusive sei que alguns leitores já se adiantaram e geraram essas classes por conta própria, através de nossa explicação anterior. Só irei fazer alguns comentários sobre este processo:

  1. Os BOs e as intefaces devem ser geradas na pasta AgendaTelefonica.BO e na pasta BO da biblioteca AgendaTelefonica.Interface, respectivamente. O RSClass – Gerador de Classes já sabe disso e gera os arquivos no local correto de acordo com as configurações realizadas anteriormente.
  2. Também, o BOFactory e o IBOFactory devem ser gerados. Não se preocupe com DAOAccess. Ele também foi gerado no momento em que voce gerou os BO’s.
  3. No Visual Studio, após ter sido gerado os arquivos, selecione as classes e, clicando com o botão direito do mouse em algum dos arquivos selecionados, selecione a opção “Include In Project“. Isso deve ser feito em cada biblioteca onde os arquivos novos foram gerados.
  4. Tembém será necessário “Add Reference…” no projeto AgendaTelefonica.BO para os arquivos Regisoft.dll e Regisoft.Camadas.Interface.dll e Microsoft.Practices.Unity.dll. Claro! Toda essa estrutura utiliza a Regisoft Library.NET pra agilizar o processo. Esses arquivos podem ser encontrados na pasta onde voce instalou o RSClass – Gerador de Classes. Se voce quiser adquirir os fontes para estudar, guardar, aprimorar… acesse a página “Sistema c/ Fontes” e saiba como.
  5. Após a realização dos procedimentos o Solution Explorer estará assim:

É importante conhecer o conteúdo dos arquivos gerados e entender seu funcionamento. Destaque para os arquivos

  • DAOAccess.cs, que se comunica com a camada DAO através do DAOFactory.cs;
  • BOFactory.cs que será a via de comunicação entre a camada de apresentação e a regra de negócio.
  • IBOFactory.cs que é a interface de exposição do BOFactory.cs

Aproveite e olhe a estrutura dos arquivos BOs gerados, por exemplo CidadeBO.cs. Veja que nele e em todos os outros BOs existe uma estrutura inicial com aquelas funcionalidades principais e comuns a todos os arquivos de regra de negócio (valiação, inserção, exclusão, etc.). Note também que no construtor do BO existe a ligação com o DAO correspondente e todos os métodos fazem uso desta instãncia do DAO.

Não é necessário ter um BO para cada DAO correspondente. Voce pode agrupá-los em funcionalidades próximas na sua aplicação, criando assim uma visão de módulo. Por exemplo, voce pode embutir em um único BO as funcionalidades para controlar endereços. Neste BO irá conter todos os métodos para gerenciar endereços: UF, Cidade, CEP, etc. Assim, na camada de apresentação, voce pode fazer uso de um certo EnderecoBO e nele já possuir tudo que se precisa pra controle de endereço: seleções, inclusões, alterações, seleções de Ufs, cidades, ceps, etc’s. Inclusive está é a atitude mais comum no que diz respeito a criação de BOs. Eu prefiro usar um BO para cada DAO. Se eu precisar, posso chamar um BO a partir de outro, facilmente. Por exemplo, A classe CidadeBO faz utilização da Classe UsuarioBO. Voce pode notar que existe um construtor da classe que recebe o UsuarioBO como parâmetro, ou seja, há uma injeção de dependência nessa classe. A classe UsuarioBO é injetada na classe CidadeBO. Quem faz isso? O BOFactory. Por isso que todas as chamadas tem que passar por ele, da mesma forma que acontecia no DAO. Isso por que se houver uma dependência de uma classe em outra, ele a injeta. Mas especificamente, quem injeta? O Framework Microsoft.Practices.Unity que foi mencionado anteriormente. É pra isso que ele serve. E a inversão de controle, onde está? Sempre que um BO chamar um DAO ele o faz pelo DAOAccess. Isso é a inversão. O controle está em outra classe e não na que realmente deveria controlar (risos: um forma bem genérica de explicar). Note que no contrutor da classe CidadeBO tem a inversão de controle da chamada para a classe CidadeDAO:

IDAOFactory daoAccess = DAOAccess.GetDAOFactory();
cidadeDAO = daoAccess.CidadeDAO();

O objetivo disso tudo é desacoplar, ou seja, nenhuma classe depende diretamente de outra. A independência é gerada através das interfaces de cada classe. Nenhuma classe instancia outra, ou seja, ninguém faz um new em objetos. Apenas os responsáveis (factorys). Outro assunto é a destruição da classe. Uma boa prática e destruir tudo que foi construído. Note que quando o Dispose() de uma classe é chamado pelo GC (Garbage Collection), tudo que foi injetado nela, também é destruido com ela, seja pela inversão de controle, seja pela injeção de dependência.

Bom… Deixando de lado essa explicação técnica e voltando ao processo, certamente durante o desenvolvimento da camada de apresentação será necessário criar vários novos métodos para operações de seleção de dados e/ou persistência, tanto nos DAOs quanto nos BOs. Sempre que criar um novo método em uma classe, lembre-se de adicionar a definição desse método à interface correspondente. Isso para que os Factorys e os Access realizem com exatidão seu papel de expor e acessar as funcionalidades da camada inferior.

Montamos o arquiterura que dará suporte a aplicação. No próximo post estaremos criando o projeto do site para camada de apresentação. Vamos gerar um prótótipo funcional para gerenciamento das tabelas da aplicação. Esse protótipo servirá de base no entendimento do processo e criação das outras telas da aplicação propriamente dita. Vamos criar também novos métodos em alguns DAOs e BOs para mostrar um pouco do potencial do NHibernate nesta questão.

Na pasta de instalação do RSClass – Gerador de Classes voce pode encontrar os arquivos deste tutorial gerados até aqui (PARTE V). Fiquem a vontade para comentar. Espero que estejam gostando e até o próximo!

Anúncios