Quando planejamos uma aplicação devemos ter em mente que, independente do público alvo inicial, uma aplicação deve estar preparada para atender, mesmo que em um único segmento, clientes que podem ir desde um único terminal (com um único usuário) até grupos empresariais (com dezenas ou centenas de filiais). Para atender este segundo cenário, as empresas geralmente, por possuírem aplicações construídas em apenas duas camadas (Cliente/Servidor), utilizam a conexão direta ao banco de dados através de redes de alta latência (Interna/Internet), ou a replicação em lotes da informação entre vários servidores de bancos de dados, os quais também utilizarão redes de alta latência para isso. Além desse tipo de aplicação, as empresas utilizam o serviço do Windows Terminal Server para integrar as unidades e possibilitar a centralização do processamento e armazenamento de dados.

As desvantagens em utilizar qualquer uma destas soluções são inúmeras: alta latência e desempenho geral da aplicação altamente prejudicado, possibilidade de inconsistência de informações, falhas de replicação, elevados custos em infraestrutura para atender a virtualização de terminais, etc. Isso, sem citar a falta de segurança dos protocolos de bancos de dados que podem fazer com que dados críticos trafeguem como texto plano pela rede.

Esta última situação pode ser contornada adicionando à comunicação protocolos de criptografia e compressão providos por outros componentes de software. Isso resolve o problema de segurança, mas traz mais um empecilho: este componente adicionado à comunicação implica, obviamente, em uma carga extra de processamento em ambas as pontas da comunicação. Alguns dirão: "mas com os computadores atuais, esta carga adicional pode ser desprezível". Talvez, mas dependendo da latência da rede, mesmo comprimido e criptografado, ambas as pontas podem enfrentar problemas com o protocolo de comunicação. Outra grande desvantagem do desenvolvimento Cliente/Servidor está nos próprios desenvolvedores, pois muitos desenvolvedores utilizam o Delphi, C#, Java, por possuírem IDEs RAD, estão tremendamente acostumados a arrastar componentes, acessar seus eventos e escrever as regras de negócio dentro deles. Isso faz com que, ao invés de cumprir apenas o seu papel, que é receber e exibir dados, a interface com o usuário também controle as regras de negócio da aplicação. Com isso, se dois ou mais formulários controlarem a mesma regra de negócio e esta estiver replicada em cada um deles, a manutenção em um único ponto não garante que esta manutenção seja replicada em cada um dos formulários, gerando divergências entre as regras.

E, por fim, aplicações Cliente/Servidor possuem um baixo índice de integralidade, fazendo com que integrações com outras aplicações sejam custosas e, na sua imensa maioria, constituídas de uma série de gambiarras artifícios técnicos dispensados para solução e/ou atendimento de necessidades levantadas segundo preceitos de engenharia de contorno. Isso faz com que a aplicação integrada tenha uma regra específica para processar as informações que serão entregues à aplicação integradora, o que pode, por falha no desenvolvimento da regra em uma das pontas, gerar divergências e erros na outra.

Visando resolver este problema, os cientistas dos laboratórios da Xerox, durante o desenvolvimento do projeto Smalltalk, criaram um modelo de análise e desenvolvimento que, até hoje, se mostra muito eficiente e que permite que vários componentes de software interajam entre si: a arquitetura multicamadas.

O que é Multicamadas

A arquitetura multicamadas estabelece que, para que um projeto seja eficiente e possua um baixo custo de manutenção e alta manutenibilidade, suas regras de negócio devem sempre ficar isoladas da interface com o usuário, de modo a não interferir em sua usabilidade e garantir a unificação do processamento dos dados relativos à aplicação. Estas regras deveriam estar igualmente isoladas dos dados a serem obtidos, manipulados ou persistidos, acoplando-se a eles o mínimo possível.

Alguns programadores acreditam que Multicamada é o MVC (Model View Controler) e isso não e verdade, tendo que MVC é um padrão de projeto enquanto Multicamada é uma arquitetura, e ocorre pela a semelhança da estrutura. Planejar e construir um software sob a arquitetura MVC não implica em um desenvolvimento multicamadas (como pode ser visto no desenvolvimento web com PHP, Java, C#), assim como desenvolvimento multicamadas não está limitado ao modelo imposto pela arquitetura MVC.

O planejamento e desenvolvimento de aplicações multicamadas resolvem, por si só, todos os problemas que o desenvolvimento Cliente/Servidor pode trazer: unifica as regras de negócio em apenas um ponto, estabelece um protocolo de comunicação mais enxuto e leve (ideal para redes de alta latência), permite a utilização de interfaces com o usuário em múltiplas plataformas, reduz os custos de manutenção da aplicação como um todo, aumenta sua manutenibilidade e, por consequência, seu ciclo de vida, etc. Ou seja, planejar e desenvolver aplicações em múltiplas camadas agrega à própria aplicação uma gama infinita de possibilidades.

Quando necessário, aplicações diversas podem integrar-se a aplicações desenvolvidas sob esta arquitetura sem a necessidade da criação de regras específicas para a esta integração. Aplicações multicamadas geralmente têm, para facilitar este processo, métodos públicos que serão utilizados para estes fins, mantendo as regras de negócio apenas na aplicação integradora, sem que a aplicação integrada tenha que inteirar-se de suas particularidades em seu desenvolvimento.

Enfim, o modelo de desenvolvimento multicamadas se mostra infinitamente superior ao modelo Cliente/Servidor, pois possibilita, ao mesmo tempo, um ganho relativamente alto de performance em cenários críticos como a possibilidade da expansão dos horizontes da própria aplicação, que pode atender desde a menor das demandas até aquelas em que o modelo de duas camadas é incapaz de atender.

Você vai encontrar em algumas literaturas divergência e visão de multicamadas entre os autores, tendo que a visão é ampla e alguns interpretam de jeitos diferentes mas com o mesmo resultado. Isso é errado? Não, pois utilizam o conceito e aplicabilidade.

Algumas literaturas tratam o assunto multicamadas como sendo uma aplicação em n camadas aquela desenvolvida de forma a ter várias camadas lógicas e cada uma é auto-contida o suficiente, de forma que a aplicação pode ser dividida em vários computadores em uma rede distribuída.

A forma mais comum da arquitetura é a aplicação em três camadas(3-Tier), comumente usada em aplicações web, na qual as camadas são:

  • Interface com o usuário (Camada de Apresentação);
  • Lógica do negócio (Camada de Negócio) e
  • Banco de dados (Camada de Dados).

Cada camada desta arquitetura é normalmente mantida em um servidor específico para tornar-se mais escalonável e independente das demais. Com o mesmo objetivo são utilizadas tecnologias de middleware como, por exemplo,CORBA,Web Services ou RMI.

Esta arquitetura tem como características:

  • Baixos custos de disponibilização;
  • Baixos custos na mudança da base de dados;
  • Baixos custos na mudança da lógica de negócios;
  • Eficiente armazenamento e reutilização de recursos.

Muitos utilizam apenas três camadas (DAL, BLL, UI) enquanto outros utilizam mais de três camadas, no caso a MODEL que trata o modelo do banco de dados.

As Figuras 1 e 2 mostram como são divididas essas camadas de forma mais intuitiva.

Modelo Multicamadas mais interativo
Figura 1. Modelo Multicamadas mais interativo
Modelo mais simples de como é a comunicação entre as camadas
Figura 2. Modelo mais simples de como é a comunicação entre as camadas

Vamos entender um pouco de cada camada:

  • Camada Apresentação (UI – User Interface Layer): A camada de apresentação fica fisicamente localizada na estação cliente e é responsável por fazer a interação do usuário com o sistema. É uma camada bastante leve que basicamente executa os tratamentos de telas e campos e geralmente acessa somente a segunda camada, a qual faz as requisições ao banco de dados e devolve o resultado. É também conhecida como cliente, regras de interface de usuário ou camada de interface.
  • Camada Regra de Negócio (BLL – Business Logic Layer): Em um sistema seguindo este modelo, a aplicação cliente nunca acessa diretamente a última camada que é a do banco de dados, pois quem tem essa função é a camada de regras de negócios, na qual podem se conectar diversas aplicações clientes.
  • Esta parte do sistema é responsável por fazer as requisições ao banco de dados e todo o seu tratamento, ou seja, somente ela que tem acesso direto ao banco de dados. É também conhecida como lógica de negócios, camada de acesso a dados, camada intermediária ou servidor de aplicação por geralmente se tratar de um outro computador destinado somente ao processamento das regras. O servidor de aplicação é uma máquina dedicada e com elevados recursos dehardware, uma vez que é nele que ficam armazenados os métodos remotos (regras de negócios) e é realizado todo o seu tratamento e processamento.
  • Camada Banco de Dados (DAL – Data Access Layer): É a última divisão do modelo, na qual fica localizado o sistema gerenciador de banco de dados. É também conhecida como camada de dados.
  • Camada Modelo (Model): Essa camada tem a finalidade de ser o modelo do banco de dados, para melhor entendimento os campos do banco. Sempre que é efetuado uma requisição de carregar informações do banco ou até mesmo pegar as informações da tela precisa de uma classe que faça esse trabalho de transpor te de informação e é essa classe que na qual eu utilizo.

Banco de Dados

Neste artigo o banco de dados a ser utilizado será o SQL SERVER 2012 que pode ser baixado no site da Microsoft.

Utilizaremos a linguagem de programação de banco de dados T-SQL para a parte do CRUD, fazendo o uso de Stored Procedures e Views. Lembrando que cada banco de dados tem um conjunto específico de comandos que definem a linguagem de programação do banco de dados no caso do SQL Server é o Transaction SQL.

Antes de tudo vamos iniciar o Management Studio. Após abrir o aplicativo, informe o Servidor, usuário e senha. Caso tenha colocado um usuário e senha, logar como autenticação do SQL Server, caso contrário colocar Autenticação do Windows, como ilustra a Figura 3.

Tela inicial do SQL Server Management Studio
Figura 3. Tela inicial do SQL Server Management Studio

Após a autenticação basta ir na opção NEW QUERY ou NOVA CONSULTA. Após a abertura, cole o script abaixo para a criação do banco de dados e observe o resultado na Figura 4:


CREATE DATABASE MULTICAMADAS 
GO
Script utilizado e o retorno do comando executado e o banco que foi criado
Figura 4. Script utilizado e o retorno do comando executado e o banco que foi criado

Após criar a tabela, será necessário reiniciar ou atualizar o Management Studio. Antes de criar as tabelas primeiro é necessário criar uma nova query e informar qual é o banco de dados que será gerado as tabelas, como ilustra a Figura 5. Em seguida crie as tabelas com o script da Listagem 1.

Informação do banco
Figura 5. Informação do banco

/* 
* TABLE: TBL_ CLIENTE
Tabela de Cliente irá armazenar o Código e Nome do Cliente.
*/

CREATE TABLE TBL_CLIENTE(
  ID_CLIENTE    int              IDENTITY(1,1),
  NM_CLIENTE    nvarchar(100)    NULL,
  CONSTRAINT PK5 PRIMARY KEY NONCLUSTERED (ID_CLIENTE)
)
go

/* 
* TABLE: TBL_ITENSPERFIL 
Tabela de Itens do Perfil armazena o código, nome, descrição, 
permissão e código do perfil dos itens do menu
*/

CREATE TABLE TBL_ITENSPERFIL(
  ID_ITENSPERFIL    int              IDENTITY(1,1),
  NM_MENU           nvarchar(100)    NOT NULL,
  DS_MENU           nvarchar(100)    NOT NULL,
  FG_PERMISSAO      nvarchar(1)      NULL,
  ID_PERFIL         int              NOT NULL,
  CONSTRAINT PK3 PRIMARY KEY NONCLUSTERED (ID_ITENSPERFIL)
)
go

/* 
* TABLE: TBL_PERFIL 
Tabela de Perfil armazena as informações referente ao perfil de usuário
*/

CREATE TABLE TBL_PERFIL(
  ID_PERFIL    int              IDENTITY(1,1),
  DS_PERFIL    nvarchar(200)    NOT NULL,
  FG_ATIVO     nvarchar(1)      NULL,
  CONSTRAINT PK2 PRIMARY KEY NONCLUSTERED (ID_PERFIL)
)
go

/* 
* TABLE: TBL_PERMISSAOUSUARIO
Tabela Permissão de usuário armazena nome do formulário, 
descrição do formulário, opção de incluir, alterar, 
excluir e o código do usuário
*/

CREATE TABLE TBL_PERMISSAOUSUARIO(
  ID_PERMISSAOUSUARIO    int             IDENTITY(1,1),
  DS_FORMULARIO          nvarchar(100)    NULL,
  NM_FORMULARIO          nvarchar(100)    NULL,
  FG_INCLUIR             nvarchar(1)     NULL,
  FG_ALTERAR             nvarchar(1)     NULL,
  FG_EXCLUIR             nvarchar(1)     NULL,
  ID_USUARIO             int             NOT NULL,
  CONSTRAINT PK4 PRIMARY KEY NONCLUSTERED (ID_PERMISSAOUSUARIO)
)
go


/* 
* TABLE: TBL_USUARIO 
Tabela de Usuário armazena o nome do usuário, login, senha, 
se está ativo, se é supre usuário e o código do perfil
*/

CREATE TABLE TBL_USUARIO(
  ID_USUARIO         int              IDENTITY(1,1),
  NM_USUARIO         nvarchar(100)    NOT NULL,
  DS_LOGIN           nvarchar(30)     NOT NULL,
  DS_SENHA           nvarchar(30)     NOT NULL,
  FG_ATIVO           nvarchar(1)      NULL,
  FG_SUPERUSUARIO    nvarchar(1)      NULL,
  ID_PERFIL          int              NOT NULL,
  CONSTRAINT PK1 PRIMARY KEY NONCLUSTERED (ID_USUARIO)
)
go


/* 
* TABLE: TBL_ITENSPERFIL
Cria o relacionamento entre a tabela de perfil e a de itens de perfil 
*/

ALTER TABLE TBL_ITENSPERFIL ADD CONSTRAINT RefTBL_PERFIL1 
  FOREIGN KEY (ID_PERFIL)
  REFERENCES TBL_PERFIL(ID_PERFIL)
go


/* 
* TABLE: TBL_PERMISSAOUSUARIO
Cria o relacionamento entre a tabela de usuário e permissão de usuário 
*/

ALTER TABLE TBL_PERMISSAOUSUARIO ADD CONSTRAINT RefTBL_USUARIO3 
  FOREIGN KEY (ID_USUARIO)
  REFERENCES TBL_USUARIO(ID_USUARIO)
go


/* 
* TABLE: TBL_USUARIO 
Cria o relacionamento entre a tabela de usuário e a tabela de perfil
*/

ALTER TABLE TBL_USUARIO ADD CONSTRAINT RefTBL_PERFIL2 
  FOREIGN KEY (ID_PERFIL)
  REFERENCES TBL_PERFIL(ID_PERFIL)
go
Listagem 1. Tabelas do banco de dados

Após a criação do banco de dados e suas tabelas vamos criar as Stored Procedures e Views. Para cada tabela serão criadas três Stored Procedures sendo uma para cada ação, tais como o create, update e delete e uma Views.

Para criar Stored Procedures existe duas maneiras. Uma é ir no menu lateral Object Explorer/Pesquisador de Objeto e clicar em cima do banco criado MULTICAMADAS: aparecerá mais algumas opções, dentre as quais escolha a opção Armazenamento/Programmability e com o botão direito clique em cima de Procedimentos Armazenados/Stored Procedure e escolher a opção Novo Procedimento Armazenado/New Stored Procedure. A outra opção é abrir uma nova Query (Consulta) e digitar os comandos para a criação.

As Listagens 2 a 4 mostram como criar as stored procedures da tabela Cliente para cada ação do CRUD.


CREATE PROCEDURE SP_TBL_CLIENTE_INSERT
    @NM_CLIENTE NVARCHAR(100)
AS
BEGIN
    INSERT INTO TBL_CLIENTE
    (
                NM_CLIENTE
    )
    VALUES
    (
                @NM_CLIENTE
    )
END
Listagem 2. Create(Insert) do Cliente

CREATE PROCEDURE SP_TBL_CLIENTE_UPDATE
    @ID_CLIENTE INT,
    @NM_CLIENTE NVARCHAR(100)
AS
BEGIN
    UPDATE TBL_CLIENTE
    SET
                NM_CLIENTE = @NM_CLIENTE
    WHERE ID_CLIENTE = @ID_CLIENTE
END
Listagem 3. Update Cliente

CREATE PROCEDURE SP_TBL_CLIENTE_DELETE
    @ID_CLIENTE INT
AS
BEGIN
    DELETE FROM TBL_CLIENTE
    WHERE ID_CLIENTE = @ID_CLIENTE
END
Listagem 4 – Delete Cliente

Após a criação da Stored Procedure iremos criar a View da tabela de cliente para recuperar os dados da tabela Cliente.

Para criar a View existem duas maneiras: uma é ir no menu lateral Object Explorer/Pesquisador de Objeto e clique em cima do banco criado MULTICAMADAS - clique com o botão direito em cima da opção Exibições/Views e vá na opção Nova Exibição/New View; ou abra uma nova Query(Consulta) e digite os comandos da Listagem 5 para a criação.


CREATE VIEW VW_TBL_CLIENTE
AS
SELECT ID_CLIENTE
  ,NM_CLIENTE
FROM TBL_CLIENTE
Listagem 5. Read(Consulta) de Clientes

As Listagens 6 a 9 mostram a criação das stored procedures e view da tabela de Usuários para cada ação do CRUD. As demais storeds procedures estarão disponíveis para download.


CREATE PROCEDURE SP_TBL_USUARIO_INSERT @NM_USUARIO NVARCHAR(100)
,@DS_LOGIN NVARCHAR(30)
,@DS_SENHA NVARCHAR(30)
,@FG_ATIVO NVARCHAR(1)
,@FG_SUPERUSUARIO NVARCHAR(1)
,@ID_PERFL INT
AS
BEGIN
INSERT INTO TBL_USUARIO (
  NM_USUARIO
  ,DS_LOGIN
  ,DS_SENHA
  ,FG_ATIVO
  ,FG_SUPERUSUARIO
  ,ID_PERFIL
  )
VALUES (
  @NM_USUARIO
  ,@DS_LOGIN
  ,@DS_SENHA
  ,@FG_ATIVO
  ,@FG_SUPERUSUARIO
  ,@ID_PERFL
  )
END
Listagem 6. Create(Insert) Usuário

CREATE PROCEDURE SP_TBL_USUARIO_UPDATE @ID_USUARIO INT
  ,@NM_USUARIO NVARCHAR(100)
  ,@DS_LOGIN NVARCHAR(30)
  ,@DS_SENHA NVARCHAR(30)
  ,@FG_ATIVO NVARCHAR(1)
  ,@FG_SUPERUSUARIO NVARCHAR(1)
  ,@ID_PERFIL INT
AS
BEGIN
  UPDATE TBL_USUARIO
  SET NM_USUARIO = @NM_USUARIO
    ,DS_LOGIN = DS_LOGIN
    ,DS_SENHA = DS_SENHA
    ,FG_ATIVO = FG_ATIVO
    ,FG_SUPERUSUARIO = @FG_SUPERUSUARIO
    ,ID_PERFIL = @ID_PERFIL
  WHERE ID_USUARIO = @ID_USUARIO
END 
Listagem 7. Update Usuário

CREATE PROCEDURE SP_TBL_USUARIO_DELETE 
    @ID_USUARIO INT
AS
BEGIN
    DELETE FROM TBL_USUARIO
    WHERE ID_USUARIO = @ID_USUARIO
END
Listagem 8. Delete Usuário

A Listagem 9 mostra a criação da view para a consulta de usuários.


CREATE VIEW VW_USUARIO
AS
SELECT T0.ID_USUARIO
  ,T0.NM_USUARIO
  ,T0.DS_LOGIN
  ,T0.FG_ATIVO
  ,T0.FG_SUPERUSUARIO
  ,T0.ID_PERFIL
  ,T1.DS_PERFIL
FROM TBL_USUARIO T0
INNER JOIN TBL_PERFIL AS T1 ON T1.ID_PERFIL 
= T0.ID_PERFIL
Listagem 9. Read(Consulta) de Usuário