Estratégia de Orientação a Objeto e Camadas com Visual Basic 6

Por Paulo Roberto Miranda Meirelles e Leonardo Ataíde Minora

Artigo para Visual Basic 6 e SQL Server
Pré-requisitos: Conhecimento de Visual Basic

O OBJETIVO DESTE ARTIGO É PROPOR UMA ADAPTAÇÃO DA ARQUITETURA DE SOFTWARE EM CAMADAS E O PADRÃO DE PROJETO VALUE OBJECT PARA SISTEMAS DESKTOP, FACILITANDO A MANUTENÇÃO DOS PROGRAMAS QUE CONTÊM TODA LÓGICA NO CLIENTE. COM ISSO, PRETENDE-SE, DEMONSTRAR A MANEIRA DE SE TRABALHAR COM PROGRAMAÇÃO ORIENTADA A OBJETOS NO VISUAL BASIC 6 (VB6), PROPORCIONANDO MELHOR VISÃO DESSE CONCEITO AOS DESENVOLVEDORES FAMILIARIZADOS COM A PROGRAMAÇÃO PROCEDURAL, BEM COMO REVELAR E DESMISTIFICAR AOS PROFISSIONAIS QUE NÃO DESENVOLVEM APLICAÇÕES COM ESSA FERRAMENTA, COMO SE PODERIA APLICAR OS SEUS CONHECIMENTOS DE ORIENTAÇÃO A OBJETOS NELA

INTRODUÇÃO

As perspectivas das tecnologias de desenvolvimento de softwares que continuarão no mercado apontam para o Java e o .Net, os quais são orientados a objeto. Nessa última, a Microsoft traz o Visual Basic (VB), também orientado a objeto. Como a antiga versão do VB é uma ferramenta de fácil utilização e aprendizado e, ainda com hegemonia da plataforma Windows, muitos profissionais o usam (ou usaram), existindo assim uma grande parte dos antigos sistemas baseados nele. Mas, hoje, não se imagina programar sem ser orientado a objeto e, cedo ou tarde, ocorrerá a migração desses sistemas para linguagens orientadas a objeto e utilizando o conhecimento da Engenharia de Software, diminuindo o alto custo de manutenção. As novas gerações de programadores, provavelmente, não chegam a trabalhar com o VB6 por este não ser naturalmente orientado a objeto e, por outro lado, os desenvolvedores VB sentem dificuldade para mudar de tecnologia, até mesmo para o VB.NET, pois sofreriam duas mudanças: a da tecnologia e o paradigma de programação. Muitos dos adeptos da Engenharia de Software e da Orientação a Objeto possivelmente se depararão com o VB no mercado de trabalho, assim como os não adeptos deverão se adequar à nova realidade. Para facilitar esses “encontros”, é proposta neste artigo a prática de alguns desses conceitos no próprio VB6.

Início da páginaInício da página

A ENGENHARIA DE SOFTWARE

O desenvolvimento de sistemas e aplicações de computação de forma não planejada e sem um padrão de estrutura e métodos gerou a “crise do software”, denominada assim por Pressman [PRESSMAN, 95]. Para sanar esse problema surge a Engenharia de Software determinando “o uso de sólidos princípios de engenharia para que se possa obter economicamente um software que seja confiável e que funcione eficientemente em máquinas reais” [PRESSMAN,95]. “A engenharia segue processos, que são maneiras pelas quais se realiza uma operação, segundo determinadas normas. O método da engenharia se baseia na ação sistemática e não na improvisação” [PÁDUA,03]. Em suma, “a engenharia de software se preocupa com o software como produto” [PÁDUA,03], com isso, o conhecimento e o seu constante estudo é de importância vital para que o software atinja o objetivo de resolver o problema proposto, sendo utilizado por outros usuários e não apenas pelo programador.

Início da páginaInício da página

A ARQUITETURA DE SOFTWARE

Com o aparecimento da Engenharia de Software, a Arquitetura de Software surge como uma parte da mesma para tratar a visão e a organização global do sistema, sendo essa ligada a fatores como qualidade e desempenho, que se tornam relevantes à medida que os softwares ficam maiores e mais complexos.

A arquitetura de software “define os componentes do sistema e o modo como estes componentes podem se comunicar” [SHAW,96]; “é uma estrutura utilizada para lidar com a complexidade de sistemas” [BASS,98] ; e “deve satisfazer os requisitos funcionais e não funcionais” [JAZAYERI,00].

Sintetizando esses conceitos, “a arquitetura é a interface entre duas partes distintas: o problema de negócio e a solução técnica” [ASTUDILLO,98].

Início da páginaInício da página

PADRÃO DE PROJETO

Um padrão é uma solução aplicada inúmeras vezes, com pequenas variações, aos problemas de um determinado contexto [GAMMA,95].

Assim, as experiências e soluções são documentadas facilitando aprendizado e utilização, uma vez que permitem uma discussão entre os desenvolvedores num maior nível de abstração, aumentando a qualidade dos softwares, e, conseqüentemente, diminuindo o seu custo de manutenção.

No estudo de caso desse artigo é utilizado o padrão de projeto Value Object que é o objeto contendo apenas dados para otimização do fluxo de informações entre as camadas [WWW1].

Início da páginaInício da página

ESTILO ARQUITETURAL

“O estilo arquitetural pode ser o ponto de partida em um projeto de software” [MENDES,02].

Um Estilo Arquitetural é a descrição dos componentes do projeto de software e do padrão existente para interação entres esses componentes.

A escolha de um estilo, dentre os vários, deve ser baseada nos requisitos e nas prioridades do software. Pensando na manutenção de softwares é que trataremos neste artigo especificamente do Estilo Arquitetural, conhecido por Camadas.

Início da páginaInício da página

CAMADAS

O modelo em camadas proporciona uma divisão dos módulos do sistema em grupos de acordo com sua tarefa, “onde cada camada acrescenta um nível de abstração sobre camada inferior” [MENDES, 02], assim facilitando a manutenção do software, bem como a integração dos programadores, que podem ficar responsáveis por cada módulo em um mesmo caso de uso, agilizando o desenvolvimento.

“Cada camada pode ser composta por vários componentes que interagem entre si ou com os componentes da camada seguinte” [BUSCHMANN, 96]. “As requisições são movidas do nível mais alto para o nível mais baixo.

As respostas para as requisições ou notificações de eventos trafegam no sentido oposto” [BUSCHMANN, 96]. Buschmann também cita a reutilização das camadas, a padronização e a manutenção das dependências localmente como as vantagens desse modelo. Porém, comenta que existem desvantagens, como a mudança de comportamento em cascata provocando alterações em mais de uma camada e queda na performance do sistema [BUSCHMANN, 96].

Mesmo com as desvantagens citadas, o modelo em camadas é uma alternativa para melhor organização de sistemas que exigem modificações rotineiras, e, como exemplo, podem ser citadas as aplicações que são intimamente ligadas às leis e resoluções legais, passivas de alterações rotineiras.

Para melhor entendimento desse modelo é importante compreender sua evolução, descrita nos subitens a seguir, baseada no que diz Macoratti [WWW2].

Uma Camada: Na época dos MainFrames - computadores de grande porte - e do computador pessoal independente, um software era desenvolvido para rodar em uma única máquina. Todas as suas funcionalidades se encontram em um único módulo, ou seja, a parte de interação com usuário, lógica de negócio e acesso ao banco de dados no mesmo lugar, com isso contendo inúmeras linhas de código, e conseqüente manutenção complexa.

Duas Camadas: O banco de dados foi colocado em uma máquina específica – servidor de banco de dados - devido à necessidade das informações serem compartilhadas simultaneamente entre vários usuários. Nos clientes é executado o software contendo toda a lógica da aplicação – denominado “cliente rico ou gordo”.

Três Camadas: Com a expansão da Internet surgem as aplicações Web, onde os usuários podem acessa-las através de um navegador, sem ter que instala-las em suas máquinas locais. Com isso, além do servidor de banco de dados, a lógica de negócio fica separada, em um servidor Web - da interface com usuário – denominado “cliente pobre ou magro”.

Início da páginaInício da página

CAMADAS EM “CLIENTES RICOS”

Há sistemas que são distribuídos em diferentes localidades para se coletar informações, mas, em certos locais, não há como estabelecer, ao menos, uma conexão com a internet ou manter uma comunicação remota. Assim, para enviar os dados à base central utiliza-se disquete, por exemplo. Com isso, impossibilita-se a separação “física” dos módulos do programa.

Também existem softwares que podem ser desenvolvidos para funcionar em apenas uma máquina, ou ainda serem instalados em diferentes estabelecimentos que não possuem relação alguma com os outros. Nessas situações acima citadas, e em outras, é necessária uma aplicação cuja lógica completa do sistema esteja apenas no cliente, c a r a c t e r i z a n d o assim o “cliente rico”. Quando isso ocorre é comum os desenvolvedores, principalmente os que usam ferramentas como o VB6, programarem as regras de negócio e a persistência com o banco de dados na mesma camada, a de apresentação, ou seja, no formulário que tem interação com os usuários finais, ocasionando dificuldades de manutenção, de entendimento daqueles que não participaram da codificação, de uma possível engenharia reversa e ainda da reutilização, no caso de uma mudança para Web.

Então é proposto um modelo em camadas de desenvolvimento para aplicações com as características acima relatadas (Figura 1).

Visão: Camada que consiste nas telas que irão interagir com o usuário, ela instancia uma classe responsável pela regra de negócio.

Modelo: São as classes que, quando instanciadas, serão os Value Object, que transitam entre as camadas.

Negócio: As classes dessa camada são responsáveis pelas validações dos campos, cálculos e outros tipos de regras pertinentes ao caso de uso. Nelas são instanciadas as classes do modelo e de persistência.

Persistência: Camada que se comunica com o banco de dados para gravar, consultar ou excluir as informações.

Implementando Camadas em “clientes ricos” com o Visual Basic 6 O Caso de uso para a exemplificação do que foi tratado nesse artigo é um cadastro de usuário de um determinado sistema (Figura 2).

Primeiramente vamos construir a classe Usuario, pertencente à camada de modelo. Uma classe pode ser modelada em ferramentas case como o Power Designer, o qual gera o código da classe para o VB6, ou de forma manual. Para isso é necessário selecionar um novo Class Module, como mostrado na figura 3.

A implementação da classe Usuario fica da seguinte forma:

Option Explicit
‘ Attributes
Private mStr_Login As String
Private mStr_Senha As String
Private mStr_Nome As String
Private mInt_Perfil As Integer
‘ Properties
Public Property Get str_Login() As String
str_Login = mStr_Login
End Property
Public Property Let str_Login(ByRef newStr_Login As String)
mStr_Login = newStr_Login
End Property
Public Property Get str_Senha() As String
str_Senha = mStr_Senha
End Property
Public Property Let str_Senha(ByRef newStr_Senha As String)
mStr_Senha = newStr_Senha
End Property
Public Property Get str_Nome() As String
str_Nome = mStr_Nome
End Property
Public Property Let str_Nome(ByRef newStr_Nome As String)
mStr_Nome = newStr_Nome
End Property
Public Property Get int_Perfil() As Integer
int_Perfil = mInt_Perfil
End Property
Public Property Let int_Perfil(ByRef newInt_Perfil As Integer)
mInt_Perfil = newInt_Perfil
End Property

A codificação das demais classes: ngcUsuario, da camada de negócio, e bdUsuario, da camada de persistência, é semelhante, sendo que, trabalha-se com Function conforme será mostrado no detalhamento do caso de uso.

Iniciaremos um cadastro de usuário pela camada superior até passarmos por todas as outras (Figura 4).

Acionando-se o botão GRAVAR será chamado o seguinte método:

Option Explicit
Dim negocio As ngcUsuario
Private Sub cmdGravar_Click()
Dim msg As String
Set negocio = New ngcUsuario ‘criando o objeto
msg = negocio.GravaUsuario(txtNome, cmbPerfil.ListIndex, txtLogin, txtSenha,
txtConfirmaSenha)
MsgBox msg, vbInformation, “Mensagem”
Set negocio = Nothing ‘ retirar objeto da memória
End Sub
Criado o objeto de negócio, através do método GravaUsuario, é feita a passagem
dos valores dos campos por parâmetros. Nele é criada a instância da classe
usuário e da classe responsável pela persistência dos dados, conforme abaixo:
Option Explicit
Dim bd As bdUsuario
Dim objUsuario As Usuario
Public Function GravaUsuario(ByVal nome As String, ByVal perfil As Integer, ByVal
login As String, ByVal senha As String, ByVal confirmaSenha As String) As String
On Error GoTo TrataErros
Dim msg As String ‘declaração de variável local
If (Trim(nome) = vbNullString) Then
GravaUsuario = “Campo Nome do Usuário Inválido”
Exit Function
End If
If perfil = -1 Then
GravaUsuario = “Perfil Inválido”
Exit Function
End If
If (Trim(login) = vbNullString) Then
GravaUsuario = “Campo Login Inválido”
Exit Function
End If
If (Trim(senha) = vbNullString) Then
GravaUsuario = “Campo de Senha Inválido”
Exit Function
End If
If (Trim(senha) <> Trim(confirmaSenha)) Then
GravaUsuario = “Campo de Confirma Senha diferente da Senha.”
Exit Function
End If
Set objUsuario = New Usuario
objUsuario.str_Nome = nome
objUsuario.int_Perfil = perfil
objUsuario.str_Login = login
objUsuario.str_Senha = senha
Set bd = New bdUsuario
GravaUsuario = bd.InserirUsuario(objUsuario)
exit_Codigo:
On Error Resume Next
Set bd = Nothing ‘retirando objeto da memória
Set objUsuario = Nothing
Exit Function
On Error GoTo 0
TrataErros:
GravaUsuario = “Erro ao Tentar Validar Usuário.”
Resume exit_Codigo
End Function

Ao ser criado o objeto de persistência, no seu método de inicialização, é realizada a conexão com banco de dados, assim como, quando é retirado da memória, é fechada a conexão com banco. Os métodos do objeto “bd” recebem como parâmetro um usuário, de acordo com a implementação abaixo:

Option Explicit
Private sql As String
Public Function InserirUsuario(ByVal pUsuario As Usuario) As String
On Error GoTo TrataErros
sql = “Select * from Usuario where str_login=’” & pUsuario.str_Login & “’”
abrirRs sql
If (rs.EOF And rs.BOF) Then
sql = “Insert into Usuario (str_Login, str_Senha, str_Nome, int_Perfil)”
sql = sql & “ Values (‘” & pUsuario.str_Login & “’,”
sql = sql & “ ‘” & pUsuario.str_Senha & “’,”
sql = sql & “ ‘” & pUsuario.str_Nome & “’,”
sql = sql & “ “ & pUsuario.int_Perfil & “)”
cn.Execute sql
InserirUsuario = “Usuário Inserido com Sucesso.”
Else
InserirUsuario = “Login do Usuário Existente.”
End If
exit_codigo:
fecharRs
On Error GoTo 0
Exit Function
TrataErros:
InserirUsuario = “Erro ao Tentar Inserir Usuário.”
End Function
Private Sub Class_Initialize()
AbrirConexao
End Sub
Private Sub Class_Terminate()
fecharConexao
End Sub

As funções para abrir e fechar conexão como banco de dados e instanciar e retirar o RecordSet ficam em um módulo (Module) separado, conforme a figura 5.

Denominaremos o módulo de Conexao.bas. Declarando um objeto de conexão (“cn”) e outro de Recordset (“rs”) - como públicos. Assim os métodos do objeto de persistência têm acesso aos mesmos:

Option Explicit
Public cn As ADODB.Connection
Public rs As ADODB.Recordset
Public Function abrirRs(ByVal sql As String)
On Error GoTo TrataErros
Set rs = New ADODB.Recordset
rs.Open sql, cn
Exit Function
TrataErros:
MensagemErro “erro RS”
End Function
Public Function fecharRs()
On Error Resume Next
If Not rs Is Nothing Then
rs.Close
Set rs = Nothing
End If
End Function
Public Function AbrirConexao()
On Error GoTo TrataErros
Set cn = CreateObject(“ADODB.connection”)
cn.Open “Provider=Microsoft.Jet.OLEDB.4.0;Data Source=” & App.Path &
“\BD.mdb” & “;Persist security Info=false”
Exit Function
TrataErros:
MensagemErro “Erro ao Tentar Abrir Conexão com o Banco de Dados.”
End Function
Public Function fecharConexao()
On Error Resume Next
cn.Close
Set cn = Nothing
End Function

Mas antes de implementar a conexão com banco de dados é necessário fazer referência à biblioteca ADO (ActiveX Data Objects ), como mostrado nas figuras 6 e 7.

Selecionar Microsoft ActiveX Data Object 2.5 Library (Figura 7).

Uma observação importante é sempre ter o cuidado de tirar os objetos da memória dando um “Close” e/ou atribuindo a eles “Nothing”, pois o VB6 não possui um coletor de lixo, assim a falta desses comandos pode prejudicar a performance do Software.

Início da páginaInício da página

CONCLUSÃO

Apesar de não tratarmos dos três pilares da orientação a objeto - Herança, Polimorfismo e Encapsulamento -, com o caso de uso apresentado, constata-se a possibilidade de desenvolver uma aplicação no VB6 utilizando os conceitos da Engenharia de Software, Arquitetura de Software e Padrão de Projeto. Com isso, esperando facilitar a compreensão desses conceitos para os profissionais dessa e de outras ferramentas de desenvolvimento, assim como para aqueles que começarão aprender a programar.

Num exemplo como o mostrado, comparando com o modelo convencional, é evidente que escrevemos algumas linhas de código a mais, porém, as vantagens superam isso, como a possibilidade de agilizar a codificação, tendo um desenvolvedor para cada camada do caso de uso, e também a fácil incorporação de um componente da equipe que comece no decorrer do projeto, por exemplo, implementando a persistência.

A qualidade, o curto prazo e o baixo custo da manutenção do software são características que um cliente procura, ou seja, no momento em que se optar por ter um código organizado, possibilitando seu fácil entendimento e reaproveitamento, já será um grande passo que os desenvolvedores de softwares darão.

Para se aprofundar

[ASTUDILLO,98] ASTUDILLO, Hernán, HAMMER, Stuart. “Understanding the Architect’s Job”, Software Architecture Workshop of OOPSLA’98, 1998.

[BASS,98] BASS, Len, CLEMENTS, Paul, KAZMAN, Rick. “Software Architecture in Pratice”, Addison Wesley, 1998.

[BENNETT,96] BENNETT, Douglas. “Designing Hard Software: The Essential Tasks”, Manning, 1996.

[BUSCHMANN,96] BUSCHMANN, Frank, MEUNIER, Regine, ROHNERT, Hans, SOMMERLAD, Peter, STAL, Michel, “A System of Patterns. Pattern-Oriented Software Architecture”, Wiley, 1996.

[GAMMA, 95] GAMMA, Erich, HELM, Richard, JOHNSON, Ralph, VLISSIDES, John, BOOCH, Grady (Designer), “Design Patterns – Elements of Reusable Object-Oriented Software”, Addison-Wesley, 1995.

[JAZAYERI,00] JAZAYERI, Mehdi, RAN, Alexander, LINDEN, Frank van der. “Software Architecture for Product Families”, Addison Wesley, 2000.

[MENDES,02] MENDES, Antônio. “Arquitetura de Software: Desenvolvimento Orientado para Arquitetura/Antônio Mendes”, Campus, 2002.

[MICROSOFT,97] “Visual Basic – Guia do Programador”. Microsoft, 1997

[PÁDUA,03] PÁDUA, Wilson de. ”Engenharia de Software - Fundamentos, métodos e padrões”.2ª edição. Rio de Janeiro, LTC, 2003.

[PRESSMAN, 95] PRESSMAN, Roger S. “Engenharia de Software”, Makron Books, 1995.

[SHAW,96] SHAW, Mary, GARLAN, David; “Software Architecture. Perspectives on an Emerging Discipline”, Prentice Hall, 1996.

[WWW1] Core J2EE Pattern Catalog, http://java.sun.com/blueprints/ corej2eepatterns/Patterns/TransferObject.html

[WWW2] José Carlos Macoratti. “Padrões de Projeto : O modelo MVC - Model View Controller”, http://www.macoratti.net/vbn_mvc.htm

* Paulo Roberto Miranda Meirelles (paulormm@yahoo.com.br) é Técnico em Processamento de Dados pelo Centro Federal de Educação Tecnológica do Rio Grande do Norte (CEFET-RN) e estudante da graduação em Tecnologia em Desenvolvimento de Software do CEFET-RN. Ministra cursos na área de informática, incluindo linguagens, programação e tecnologias de banco de dados, e trabalha com desenvolvimento de sistemas desde 2001. Há um ano é programador do Tribunal de Contas do Estado do Rio Grande do Norte. Atua, hoje, pesquisando nas áreas de Engenharia de Software, Sistemas Web e Distribuídos. Leonardo Ataíde Minora (minora@cefetrn.br) é Graduado pela Universidade Potiguar (UnP), e mestre em ciências da computação pela Universidade Federal de Santa Catarina (UFSC). Atualmente, é professor substituto do Centro Federal de Educação Tecnológica do Rio Grande. do Norte (CEFET-RN), e professor da Universidade Potiguar. Suas áreas de interesse, hoje, são engenharia de software (em específico arquitetura e modelagem ágeis), sistemas distribuídos, sistemas para dispositivos móveis, e realidade virtual distribuída.


Início da páginaInício da página