Delphi Core Aplicações multicamadas com BSS Criando sistemas multicamadas utilizando Borland Socket Server - Parte II
Neste artigo veremos · Dicas de implantação e debug das aplicações cliente e servidora; · Implementação da aplicação cliente; · Interação entre as camadas cliente e servidora; · Conceitos de orientação a objeto; Qual a finalidade? · Demonstrar a criação de uma aplicação que permita acesso remoto às informações em condições aceitáveis, apresentando uma solução que possua separação das regras de negócio e camadas de apresentação, tornando-se uma solução com possibilidade de evolução e facilidade em manutenção. Quais situações utilizam esses recursos? · Qualquer ambiente que necessite de grande disponibilidade, empresas que possuam sistemas complexos ou integração entre matrizes e filiais.
Resumo do DevMan
Sistemas multicamadas têm sido amplamente discutidos nas comunidades de tecnologia, no entanto, muitos desenvolvedores ainda possuem receios em migrar seus softwares cliente-servidor para esta arquitetura ou iniciar aplicações deste tipo, devido à falta de conhecimento ou até mesmo por achar a implementação muito complexa.
Neste artigo veremos como desenvolver um sistema em multicamadas utilizando as tecnologias DataSnap e BSS (Borland Socket Server), abordando as principais maneiras para a construção do ambiente, além dos principais conceitos para o desenvolvimento de uma aplicação com qualidade.
No artigo anterior, desenvolvemos a parte servidora da aplicação que estamos construindo. Seguindo parte do raciocínio empregado no artigo anterior, iremos iniciar o desenvolvimento da nossa aplicação cliente, realizando algumas alterações à nossa aplicação servidora para a implementação das consultas. Veremos também algumas boas práticas, como um recurso de reaproveitamento de código muito conhecido no mundo da orientação a objetos, comumente chamado de herança. Logicamente, antes mesmo de iniciarmos o desenvolvimento, não posso deixar de comentar os passos relativos ao servidor de aplicação que são de extrema importância nesta fase de desenvolvimento.
Sendo assim, o primeiro passo a ser considerado é a inicialização do nosso comunicador, o Socket Server, que encontra-se por padrão em C:\Arquivos de programas\CodeGear\RAD Studio\5.0\bin\ScktSrvr.exe. Ele é necessário para que possamos fazer a conexão de nosso sistema com o servidor de aplicação. Bem, vamos por a mão na massa e finalizar nosso sistema.
O Socket Server
O Socket Server é uma pequena aplicação que permite a comunicação da aplicação cliente com o servidor de aplicativos. Ela possui código-fonte e é free, acompanhando a instalação do Delphi. Existem duas maneiras de realizar sua instalação, sendo a primeira manualmente apenas executando o arquivo mencionado, e a outra é efetuada como um serviço que será iniciado juntamente com seu sistema operacional.
Nota: Realizando a instalação do arquivo Socket Server (ScktSrvr.exe) como um serviço, não será possível fazer o debug da aplicação servidora, portanto é recomendado que se utilize este recurso apenas no ambiente de produção ou implantação. Para registrá-lo como serviço, simplesmente abra o prompt de comandos e acesse o diretório padrão do Socket Server digitando a linha de comando scktsrvr.exe –install, para realizar o processo reverso de desinstalação do serviço apenas mude o parâmetro –install para –uninstall.
Ao iniciarmos o Socket Server, devemos nos atentar para o servidor de aplicação, pois para conseguirmos visualizá-la na aplicação cliente é necessário efetuar seu registro. Para isto, abra o projeto anterior contendo a aplicação servidora e acesse a opção Project>Options. Selecione do seu lado esquerdo a opção Debugger e na opção Parameters do lado direito, digite /regserver conforme mostra a Figura 1. Perceba que ao executar sua aplicação pressionando a tecla F9 ou através do botão Run. A princípio nada acontecerá, porém, neste momento foram criadas as GUID (Globally Unique IDentifier) dos nossos Remote Data Modules no registro do seu sistema operacional. Após ter registrado o servidor de aplicação remova o parâmetro para conseguir realizar o debug normalmente.
Nota: Ao adicionarmos um componente novo ou alterar algo em algum Remote Data Module já existente na aplicação, não é necessário registrar novamente a aplicação, sendo necessário efetuar o registro toda vez que adicionarmos um novo Remote Data Module em nossa aplicação servidora.
Figura 1. Registrando a aplicação servidora através do RAD Studio
Construindo a Aplicação Cliente
Após termos tomado estes devidos cuidados, vamos finalmente iniciar o desenvolvimento da nossa aplicação cliente, deste modo abra seu RAD Studio e acesse a opção File>New>VCL Forms Application – Delphi for Win 32 e altere as propriedades Name do formulário inicial para frmMenu, Width para 800, Height para 600, Position para poDesktopCenter e defina seu Caption como Sistema de Bibliotecas. Adicione ao formulário um componente Panel e altere suas propriedades Name para pnlTopo, limpe a propriedade Caption e por último marque Align para alTop, dentro do nosso pnlTopo adicione quatro componentes SpeedButton e altere suas propriedades Name, respectivamente para spbEditora, spbLivro, spbPessoa e spbEmprestimo. Defina a propriedade Caption para Editora, Livro, Pessoa e Empréstimo e insira quatro Glyphs conforme seu gosto, para o exemplo alterei também as propriedades Layout de cada componente para blGlyphTop dispondo as imagens ao topo e suas descrições de funcionalidades logo abaixo da figura, ao concluir as configurações selecione File>SaveAll salvando em um diretório de sua preferência a Unit como untMenu e o projeto como ClientBSS.dproj. Terminando as configurações seu formulário deve estar com a aparência semelhante ao da Figura 2.
Figura 2. Exemplo do formulário de menu da aplicação cliente
Criando o formulário de herança
Apesar de ser um assunto amplamente comentado, a herança ainda é um recurso pouco utilizado pelos desenvolvedores Delphi. Não irei entrar em muitos detalhes, pois este não é o foco do nosso artigo, mas este modelo será utilizado em todas as telas do nosso sistema, facilitando muito o trabalho, pois boa parte do código será reaproveitada.
Sendo assim, crie um novo formulário e altere suas propriedades Name para frmHeranca, Position para poMainFormCenter, Width para 624, Height para 348, BorderStyle para bsDialog e por último Caption para Formulário de Herança. Adicione a este formulário um componente Panel setando seu Name para pnlTopo e Align para alTop, dentro do Panel insira oito componentes SpeedButton e altere respectivamente suas propriedades Name para spbIncluir, spbEditar, spbExcluir, spbCancelar, spbSalvar, spbDevolver, spbPesquisar e spbSair e a propriedade Caption para Incluir, Editar, Excluir, Cancelar, Salvar, Devolver, Pesquisar e Sair no marque o Visible para False.
Ainda no Panel insira um ComboBox alterando sua propriedade Name para cmbParametros, Style para csOwnerDrawFixed e limpe o conteúdo de Text, em seguida adicione um Edit alterando o Name para edtPesquisar e dois Labels alterando seus Captions para Pesquisar por... e Texto :.
Fora do Panel adicione um componente PageControl e altere Name para pclPrincipal, Align para alClient em seguida crie duas abas ao componente clicando com o botão direito do mouse sobre o componente e selecionando a opção New Page, clique sobre a primeira e altere a propriedade Name para tbsConsulta e Caption para Consulta, em seguida clique na segunda e altere as mesma propriedades para tbsCadastro e Cadastro. Selecione a tbsConsulta e adicione um componente DBGrid alterando a propriedade Align para alClient, por último adicione dois componentes DataSource ao nosso formulário nomeando o primeiro para dsrCadastro e o segundo para dsrPesquisa, agora ligue o dsrPesquisa a propriedade DataSource do nosso DBGrid, realizando estes passos teremos concluído a parte visual de nosso formulário de herança, a Figura 3 exibe o resultado final do nosso formulário.
Figura 3. Interface do formulário de herança
Agora que concluímos a interface de apresentação dos dados vamos iniciar a codificação do formulário de herança, lembrando que toda a codificação realizada neste formulário será funcional para as demais telas de nossa aplicação.
Em nossa aplicação fazemos a utilização de dois DataSource, isso se deve ao fato de que a nossa consulta será independente do cadastro, deste modo para editarmos um registro deveremos consultá-lo antes. Vamos iniciar a nossa codificação pelos eventos mais simples, logo selecione o spbSair e no seu evento OnClick adicione o código abaixo que será responsável pelo fechamento do formulário.
Self.ModalResult := mrCancel;
Em seguida selecione o spbDevolver adicionando no evento OnClick o código abaixo :
if (dsrPesquisa.DataSet.Active) and (dsrPesquisa.DataSet.RecordCount > 0) then
Self.ModalResult := mrOk;
Este botão será responsável por fazer a devolução dos dados de pesquisa de um formulário para outro, o código acima verifica se o conteúdo dentro da propriedade DataSet (que no caso será o ClientDataSet) do componente dsrPesquisa não está vazio, e se o mesmo está aberto, caso a condição seja satisfeita o formulário simplesmente é encerrado. Adiante veremos as diferenças entre o encerramento dos botões spbSair e spbDevolver.
Selecione o frmHeranca e no evento OnDestroy coloque o código abaixo.
dsrPesquisa.DataSet.Close;
Com este código, garantiremos que toda vez que o formulário for destruído seu DataSet de pesquisa seja automaticamente fechado, fazendo com que nada fique aberto na nossa aplicação. Configuraremos agora o estado dos botões de uma forma bem simples utilizando o evento OnDataChange. Os botões estarão acessíveis de acordo com a propriedade State do nosso dsrCadastro, de forma que se previna alguns possíveis erros e garantindo um melhor controle das ações do usuário. Selecione o componente dsrCadastro e no evento OnDataChange adicione os códigos da Listagem 1, observe que os componentes spbSalvar, spbCancelar e spbExluir estarão habilitados quando o DataSet do nosso dsrCadastro estiver em estados de edição ou inserção e os botões spbIncluir e spbEditar só serão habilitados quando não estiverem em estado de inserção e edição.
Listagem 1. Evento OnDataChange do componente dsrCadastro
procedure TfrmHeranca.dsrCadastroDataChange(Sender: TObject; Field: TField);
begin
spbIncluir.Enabled := not (dsrCadastro.State in [dsInsert, dsEdit]);
spbEditar.Enabled := not (dsrCadastro.State in [dsInsert, dsEdit]);
spbSalvar.Enabled := (dsrCadastro.State in [dsEdit, dsInsert]);
spbCancelar.Enabled := (dsrCadastro.State in [dsEdit, dsInsert]);
spbExcluir.Enabled := (dsrCadastro.State in [dsEdit, dsInsert]);
end;
Nota: Toda vez que referenciamos o ...