Você está na página 1de 30

Sumário

Este documento apresenta as melhores práticas para construir aplicações com VB, ASP e
COM+.

Conteúdo

Dicas de Técnicas de Desenvolvimento Orientado a Objeto (OO)


Tecnologia COM+
Tecnologia de Acesso à Dados
Melhorando a performance de suas páginas ASP
Lições Aprendidas
Introdução ao Windows DNA
Exemplos de Código
Componentes de Acesso à Base de Dados (Data Base Services)
Componentes de Negócios (Business Services)

Dicas de Técnicas de Desenvolvimento Orientado a Objeto (OO)

Diretrizes Gerais
• Bons desenvolvedores entendem todo o processo de desenvolvimento.
• Bons desenvolvedores desenvolvem pensando na manutenção do sistema, não no
desenvolvimento.
• Decisões que apressem o processo de desenvolvimento geralmente punem você
durante a manutenção.
• As decisões que melhoram a manutenabilidade de seu sistema geralmente podem
aumentar o tempo de desenvolvimento.
• Seus esforços de desenvolvimento devem ser fáceis para outras pessoas
compreenderem.
• Analise, projete de depois programe.
• Suporte seus usuários de forma proativa e em tempo.

Diretrizes para Classes


• Utilize substantivos para nome de Classes (99.9 % das vezes)
• Modele as classes pensando em “entidades” (Ex : Cliente, Parceiro, Aeronave, Item,
etc)

Diretrizes para Métodos


• Dê nomes aos métodos que comecem com verbos fortes e ativos (Ex :AbrirConta,
MostrarPartNumber, etc)
• Documentação interna do método. (Ex : o que o método faz, parâmetros de
entrada/saída, histórico de mudança de código, observações)
• Identar corretamente o código.
• Utilizar linhas em branco tornam o código mais fácil de compreender.
• Métodos devem realizar somente uma coisa.
• Faça somente uma coisa por linha de código.
• Regra dos 30 segundos : deve ser possível analisar um método e entendê-lo em menos
de 30 segundos.

Ref. Ambler, S. (1995). Análise e Projeto Orientado a Objeto

Tecnologia COM+

Utilize um padrão de nomes


Quando escrever o código para seu componente é sempre bom considerar um padrão de
nomes. Isto facilitará a manutenção de seu código, a resolução de problemas e o tornará
menos sujeito a erros.
Mais Informação
Você deve especificar um padrão para nomes para :
• Variáveis
• Classes
• Funções e Parâmetros
• Projetos
• Objetos de Banco (tables, stored procedures,etc)
How To
Abaixo segue uma sugestão para a convenção de nomes :
• Não abrevie demasiadamente (por exemplo, fopen vs. OpenFile).
• Use uma boa captalização (DeleteexpiredSubscribers vs. DeleteExpiredSubscribers).
• Use underscores consistentemente (sp_add_user vs. sp_removeuser).
• Use Plural-Singular consistentemente (SELECT * FROM Authors INNER JOIN
Book).
Vide Procedimento de Nomenclatura de Objetos MEF:004/2001

Evite códigos “pesados” no Sub Main()


Uma vez que seu componente COM+ é instanciado, seu Sub Main será invocado. Entretanto,
se você tiver código de execução demorada nesta rotina (tal como acesso a banco, carga de
arquivos grandes, parsing, etc) você pode experimentar uma mensagem de erro de “time out” .

Adquira Recursos mais tarde, Libere-os o mais cedo possível


Evite manipular recursos (abertura de arquivos, conexões com banco de dados, database
locks, memória, etc.) por mais tempo do que o necessário. Por exemplo, não estabeleça uma
conexão com o banco até que você esteja pronto para usá-la.

Programe usando operações Thread-Safe


Enquanto Visual Basic é uma linguagem muito produtiva para desenvolver “server
components”, existem certos detalhes dentro do produto que podem comprometer sua
performance no servidor. As seguintes ações não são recomendadas :
• Calling DoEvents
• Mostrar um formulário
• Invocar uma library or componente que não foi desenhado e testado para rodar no
servidor

Use “Early Binding” sempre que possível


Usando “early binding “ (isto é, declarando variáveis de object como sendo de uma classe ou
interface específica, e não como um object) aumenta a performance do componente
significativamente.
Mais Informação
Você está usando “early binding” quando está usando um objeto declarado da seguinte
maneira:
Dim oHouse As CHouse

Ou
Dim oHouse As Iasset

Você está usando “late binding” quando sua variável é declarada assim:
Dim oHouse As Object

Ou
Dim oHouse As Variant.

Declare Parâmetros como ByVal sempre que possível


Visual Basic define parâmetros por referência (By Ref) por default. Para passar estes
parâmetros por “valor” (então o parâmetro não será transmitido de volta para o chamador
usando recursos de rede desnecessários), declare os parâmetros usando a palavra-chave
“ByVal”
How To
Ex : Function GetUserName (ByVal UserId as integer)

Não use o Registro do Windows para armazenar informações da Aplicação


VB oferece algumas funções para acessar diretamente o registro do Windows para leitura e
gravação de dados. Entretanto, estas funções foram desenhadas para aplicações de desktop, e
elas lêem uma poção do registro específica para o usuário logado, através da chave
HKEY_CURRENT_USER. Para aplicações de Web que utilizam o MTS, uma outra chave
do registro poderá ser usada, dependendo do usuário logado no servidor, podendo
comprometer o funcionamento correto da aplicação.

Set Threading Model=Apartment Threaded em seu Projeto


No Visual Basic 6.0, suas DLLs podem ser tanto Single Threaded ou Apartment Threaded—
selecione Apartment Threaded, pois este é o modelo de threaded necessário para trabalhar
com o MTS.
How To
Em Project, selecione Properties, e na General tab selecione Apartment Threaded na caixa de
Threading Model.
Set Unattended Execution em seu Projecto
Este atributo especifica que seu componente irá rodar sem interface com o usuário.
How To
Em Project, clique em Properties. Na tab General, cheque a caixa Unattended Execution

Check "Retained in Memory" em Seu Projeto


Este atributo especifica a maneira que seu componente irá carregar/descarregar outras DLLs
requeridas.
How To
Em Project, clique Properties e na tab General, clique em Unattended Execution e Retained in
Memory.
.
Não use Classes Global Multi-Use
Classes Global Multi-Use são úteis para desenvolvimento client-side. Em DLLs server-side,
onde um modelo “stateless” é desejável, não utilize este tipo de classe.
How To
Você deve setar sua classe como MultiUse ao invés de GlobalMultiUse, e criá-la e destruí-la
sempre que necessário.

Não Declare Variáveis como "As New…"


Quando você declara uma variável usando a declaração “As New”, você poupa esforço para
escrever código, podendo acessar os métodos e propriedades da classe mais facilmente.
Porém, isto torna qualquer referência ao objeto mais lenta e além disso, se a classe estiver
sendo chamada dentro de um mesmo projeto, isto fará com que o mecanismo de criação de
componentes do MTS seja incapaz de manipular o objeto, perdendo o controle do contexto de
transação e segurança no qual o objeto esteja envolvido.
How To
Use New:
• Para criar objetos tais como ADO, MSXML, CDO, MSMQ.
Ex :
Set oDBConnection = New ADODB.Connection

Use CreateObject:
• Para criar objetos através do ProgID.
Ex:
Set oISPSubs = CreateObject("MyProject.CSubscription")

Saiba Quando Usar Compatibilidade Binária


Compatibilidade binária é um recurso que permite que, uma vez publicados os métodos e
parâmetros de um componente, eles não mais poderão ser alterados, ou seja, não deveremos
mais alterar o nome do método, a quantidade de parâmetros, os tipos dos parâmetros, a ordem
dos parâmetros. Desta forma, estaremos garantindo que, toda aplicação que acessa este
método continuará funcionando mesmo depois da liberação de uma nova versão do
componente, desde que respeitada a compatibilidade binária.
Enquanto o componente está em desenvolvimento, fase na qual existem alterações freqüentes
no código, devemos usar a opção de “Project Compatibility”.
How To
Step 1 : Primeira compilação do componente
Em Project, clique em Properties. Na tab Component, selecione a opção “Project
Compatibility”
Step 2 : Liberações sub-sequentes para produção :
Em Project, clique em Properties. Na tab Component, selecione a opção “Binary
Compatibility” e selecione a versão anterior da dll para referência.

Observações
Uma vez “quebrada” a compatibilidade binária, deve-se gerar o componente novamente de
acordo com o “Step 1” e verificar se isto afetará as aplicações que utilizam o componente.
Não deve-se “forçar” a compatibilidade binária (processo chamado de “interface
forwarding“), pois MTS não irá trabalhar corretamente com o componente.

Tecnologia de Acesso à Dados

Use a Última Versão do Microsoft Data Access Components (MDAC)


Windows 2000 vem com o Microsoft Data Access Components (MDAC) 2.6.
(Vide Service pack 1 para MDAC 2.6)
How To
Em Project, clique em References. Selecione Microsoft ActiveX Data Objects 2.6 library

Close and Set para Nothing seus objetos ADO tão cedo quanto possível
How To
Set oMyRecordset = Nothing

Evite Reusar Objetos de Conexão ADO para Executar Vários Comandos


O ADO possui sua própria implementação interna de “connection pooling”. Desta forma,
você deve simplesmente seguir os seguintes passos :
• Crie a conexão ADO
• Abra a conexão
• Use-a
• Feche a conexão
• Set a conexão para Nothing
Será fácil desenvolver, manter e é rápido e escalável.

Use SetComplete e SetAbort em seus métodos


Quando vocês usa estes métodos, você está dando seu “aval” para a transação corrente e
dizendo para o COM+/MTS que você está pronto para ser desativado (destruído ou set para
Nothing na linguagem do VB). Isto permite um melhor encapsulamento da lógica e assim
aumenta as oportunidades de reutilização de código.
How To
Use o método GetObjectContext.SetComplete antes de retornar de seu método. Na sua rotina
de manipulação de erros, chame GetObjectContext.SetAbort.

Não use Data Environments em Componentes Server-side


Os Data Environments do Visual Basic 6.0 facilitam a interface com o banco de dados,
porém para componentes que rodarão no servidor sob o MTS ou COM+ , não recomenda-se o
seu uso.

Melhorando a performance de suas páginas ASP


Assuntos

• Páginas ASP;
• Uso de Componentes e
• Acesso a Dados.
Páginas ASP

Gerando Conteúdo com ASP

Uma das justificativas mais importantes para o uso de ASP é a geração de conteúdo dinâmico.
Existem algumas formas para fazê-lo, e a mais indicada é usar o método Write do objeto
Response (Response.Write) em uma única instrução como mostra o seguinte exemplo:
...
Response.Write(“<html>” & _
“<head>” & _
“<title>Gerando Conteúdo com ASP</title>” & _
“</head>” & _
“<body>” & _
“<h1>Gerand Conteúdo com ASP</h1>” & _
“<table>” & _
“<tr><td><b>Nome:</b></td><td>” & strNome & “</ td></tr>” & _
“<tr><td><b>Aniverssário:</b></td><td>” & dtmAniverssario & “</td></tr>” & _
“</table>” & _
“</body>” & _
“</html>”)
...
Isto se justifica pelo fato de que o interpretador ASP precisa apenas interpretar uma única
instrução para exibir o conteúdo desejado.

Uso de Quebras de Linha

Quando se envia conteúdo para o browser da maneira descrita anteriormente, todo o conteúdo
fica em uma única linha no código fonte exibido no browser. Se você se preocupa em como o
código será exibido no browser, você poderá utilizar a constante vbCrLf concatenada ao
conteúdo enviado através do método Write para inserir quebras de linha. Isto acarretará uma
pequena queda na performance, mas que é suportável nos casos onde a formatação do código
fonte é importante, como mostra o seguinte trecho de código:
...
Response.Write(“<html>” & vbCrLf & _
“<head>” & vbCrLf & _
“ <title>Gerando Conteúdo com ASP</title>” & vbCrLf & _
“</head>” & vbCrLf & _
...

Uso de Comentários no Código

O uso de comentários em páginas HTML não é algo muito interessante pois aumenta a
quantidade de informações que é transferida do Servidor Web para o Browser, e só tem
utilidade para os programadores da página. Entretanto, os comentários no código ASP não
representam uma mudança significativa na performance das páginas pois são simplesmente
ignorados pelo interpretador e não são transferidos para o browser.

Scripts Muito Longos

Obviamente, você pode incluir suas regras de negócio em páginas ASP, pois elas são
processadas no Servidor Web. Entretanto, isto pode tornar os seus scripts muito longos.
Não podemos perder de vista que todo código ASP é interpretado linha a linha. Dessa
maneira, scripts muito longos podem se tornar muito lentos. Nestes casos, a melhor maneira é
usar Componentes que encapsulem as regras de negócio em código compilado.

Arquivos “#include” Muito Longos

Os arquivos de include são uma ótima opção para economizar linhas de código que podem ser
reutilizadas em diversas páginas. Entretanto, existe uma pequena diminuição na performance
de páginas ASP que usam includes. Principalmente se eles forem muito longos. Mesmo que
você esteja usando apenas parte de um arquivo de include, como nos casos onde eles
funcionam como uma biblioteca de rotinas, todo o arquivo de include é interpretado antes da
informação chegar até o browser.
Este é mais um motivo que nos motiva a usar componentes compilados em páginas ASP.

Uso de Variáveis Globais

Sempre que possível, evite o uso de variáveis globais. As variáveis declaradas dentro de
subrotinas ou funções são acessadas mais rapidamente e deixam o código mais limpo e
organizado.

Uso de Option Explicit

Além de ser uma ótima prática de programação, o uso da instrução Option Explicit, que
obriga a declaração de variáveis, torna o processamento da página mais rápido.

Uso de Blocos de Função

O uso de Blocos de Função diminui a performance das páginas ASP devido às chamadas
extras que se fazem necessárias a esses blocos. Entretanto, o fato de nesses casos algumas
variáveis se tornarem locais dos blocos, faz com que seja vantajoso o uso de Blocos de
Função.
Dessa maneira, sempre que se fizer necessário o uso de blocos de função para economizar
código, faça-o e use variáveis locais sempre que possível.

Tratamento de Erro

Tratamento de Erros é essencial em aplicações sérias. Mas existe uma pequena queda na
performance das páginas que possuem tratamento de erro. Dessa maneira, o bom senso diz
que o tratamento de erro deve ser usado sempre que você não tiver controle sobre os erros que
possam acontecer em sua aplicação. Um bom exemplo é quando você usa objetos que
acessam outros recursos, tais como ADO ou FileSystem.
Uso de Transações

O uso de transações (<%@ TRANSACTION = REQUIRED %>) causa uma queda dramática
da performance de páginas ASP. Dessa forma, apenas use transações quando duas ou mais
operações precisem ser realizadas de uma única vez.

Uso de código ASP e HTML Alternado

Evite intercalar código ASP com código HTML, como no exemplo que se segue:
...
<% For intContador = 1 To 10 %>
<TR><TD>Contando ... <%= intContador %></TD></TR>
<% Next %>
...

Preferencialmente, agrupe o código ASP em blocos sempre que possível:


...
<%
For intContador = 1 To 10
Response.Write “<TR><TD>Contando ... “ & intContador & “</TD></TR>”
Next
%>
...

Uso de Buffer

Você pode determinar que o conteúdo de sua página ASP seja exibido somente depois de todo
o processamento da página através da propriedade Response.Buffer = True.
Isto é uma boa prática, pois aumenta a performance de processamento das páginas ASP. Mas
em alguns casos, é necessário enviar alguma informação ao cliente durante o processamento
das páginas. Nestes casos, use Response.Buffer = False ou use o método Response.Flush para
enviar as informações processadas até o momento para o browser.

Desabilitar o Controle de Estado Quando Possível (Local e Server)

O controle de estado é algo muito interessante que as páginas ASP nos proporcionam.
Entretanto, existe uma queda na performance de páginas que fazem uso deste recurso.
Desta maneira, sempre que o controle de estado não se fizer necessário em uma página, use a
seguinte instrução para desabilitá-lo: <%@ENABLESESSIONSTATE = FALSE %>.
Se nenhuma das páginas de seu site fizer uso de controle de estado, você pode configurar
diretamente nas propriedades do site. Para isto, selecione a caixa de diálogo Properties do site
em questão. Em seguida, selecione o botão Configuration na aba Home Directory.
Desmarque, então, a opção enable session state em App options.

Uso de Arrays Dinâmicos

O uso da instrução Redim nos economiza um pouco de memória e a preocupação de estourar


o número limite de elementos dos arrays em nossos códigos. Entretanto, o uso de Redim
provoca uma queda na performance. O ideal é usar a instrução Dim já com a quantidade de
elementos que será usada. Mesmo nos casos em que você não sabe a quantidade exata, o uso
de uma ordem de grandeza, com o risco de ocupar alguns espaços desnecessários da memória,
compensa em função da velocidade.

Uso da Propriedade IsClientConnected

Sempre que sua página ASP tiver um longo processamento, use o método
Response.IsClientConnected para verificar se o cliente ainda está conectado. Caso contrário,
você poderá abortar o processamento evitando, assim, o consumo desnecessário de recursos
do servidor.

Uso do Mesmo Objeto Muitas Vezes

Se você for usar o mesmo objeto muitas vezes e estiver usando o VBScript 5.0, faça uso da
instrução With para que não seja necessário requalificar o objeto a cada propriedade ou
método usado:
...
With Response
.Write “Linha 1<BR>”
.Write “Linha 2<BR>”
.Write “Linha 3<BR>”
.Flush
.Write “Linha 4<BR>”
.Write “Linha 5<BR>”
.Write “Linha 6<BR>”
End With
...
Eventos Session_OnStart ou Session_OnEnd

Sem Conteúdo

Remova eventos do objeto Session que não tenham conteúdo. Isto economizará passos do
interpretador, aumentando a performance.

Acesso aos Dados

Uso de Índices

Sempre que possível, faça uso de índices em seus bancos de dados. Os índices aumentam
incrivelmente a performance de consultas e stored procedures acessadas via ADO em páginas
ASP.

Retornando Apenas o Necessário

Certifique-se que suas consultas estão retornando apenas os campos necessários. Nos casos de
consultas que retornam muitos registros, tente paginar a consulta de forma que ela retorne
apenas alguns registros de cada vez. Isto poderá aumentar bastante a performance de suas
páginas ASP.

Versão do Microsoft Data Access Components (MDAC)


Procure usar o MDAC 2.6 com Service Pack 1 ou superior.

Armazenando Connections ADO em Variáveis de Aplicação ou de Sessão

Jamais armazene objetos Connection em variáveis de Aplicação ou de Sessão. O ADO já


possui um mecanismo chamado pooling que otimiza o uso de instâncias de conexões. Além
do mais, como foi visto anteriormente, não é uma boa idéia armazenar instâncias de objetos
em variáveis de Sessão.
Instancie suas Conexões diretamente na página em questão e não esqueça de atribuir Nothing
a elas quando terminar o uso.

Fechar Explicitamente Recordsets e Connections

Tanto objetos Recordset como Connection devem ser fechados explicitamente através do
método Close assim que termine o seu uso. Desta forma, você os disponibiliza para o pooling
do ADO.

Reutilização de Recordsets e Commands

Evite a reutilização de objetos Recordset e Command. Isto não necessariamente irá aumentar
a performance de suas aplicações, mas sua aplicação ficará mais clara e mais fácil de dar
manutenção.

Utilizando o Tipo de Cursor (Cursor Type) e o Tipo de Bloqueio (Lock Type) Mais Eficientes

Use sempre o tipo de cursor e o tipo de bloqueio mais simples para a tarefa que você deseja
realizar.
A tabela 1 mostra em ordem decrescente de performance os tipos de cursor e tipos de
bloqueio.

Cursor Types Lock Types


Forwardonly ReadOnly
Static Batchoptimistic
Dynamic Optimistic
Keyset Pessimistic
Tabela 1 - Tipos de cursor e tipos de bloqueio em ordem decrescente de performance

Uso de GetRows

O método GetRows atribui todo o conteúdo de um Recordset para um vetor bidimensional,


cuja primeira dimensão representa os campos e a segunda representa os registros. Logo em
seguida, o Recordset pode ser fechado. O uso de GetRows aumenta muito a performance de
páginas ASP:
...
If objRS.EOF Then
Response.Write (“Não foram encontrados registros.”)
objRS.Close
Set objRS = Nothing
Else
Dim arrRS
arrRS = objRS.GetRows
objRS.Close
Set objRS = Nothing

Dim NumRegistros
Dim NumCampos
Dim RegistroAtual
Dim CampoAtual

NumCampos = Ubound(arrRS, 1)
NumRegistros = Ubound(arrRS, 2)
Response.Write “<TABLE>”
For RegistroAtual = 0 To NumRegistros
Response.Write “<TR>”
For CampoAtual = 0 To NumCampos
Response.Write “<TD>” & arrRS(CampoAtual, RegistroAtual) &
“</TD>”
Next
Response.Write “</TR>”
Next
Response.Write “</TABLE>”
End If
...

Conexões Sem DSN

As conexões sem DSN normalmente são mais rápidas que as conexões usando DSN de
sistema, que por sua vez são mais rápidas que as conexões usando DSN de arquivo.
As conexões em DSN são aquelas cujos parâmetros de conexão são passados diretamente no
momento da criação da conexão.

Uso do Provider OLEDB

Usar sempre o MS Provider para Oracle.

Uso do arquivo ADOVBS.inc

Evite o uso do arquivo ADOVBS.inc que contém as declarações das constantes usadas pelo
ADO. Ao invés disso, declare apenas as constantes que você irá usar ou coloque a seguinte
referência em seu arquivo global.asa:
<!--METADATA TYPE=”typelib” FILE=”c:\arquivos de programas\arquivos
comuns\system\ado\msado15.dll” NAME=”ADODB Type Library” -->
ou <!--METADATA TYPE=”typelib” UUID=”00000205-0000-0010-8000-
00AA006D2EA4" NAME=”ADODB Type Library” -->
ou uma versão superior.

Uso de um Objeto Connection Separado Quando Trabalhar com Recordsets


Se você estiver usando um único Recordset, passe a string de conexão diretamente para a
propriedade ActiveConnection:
objRS.ActiveConnection = Application(“ConexaoString”)
Quando você estiver utilizando vários Recordsets, crie um objeto Connection e use-o na
propriedade Active Connection:
...
Set objConn = Server.CreateObject(“ADODB.Connection”)
objConn.Open Application(“ConexaoString”)

Dim intContador
For intContador = 1 To 10

Set objRS = Server.CreateObject(“ADODB.Recordset”)


Set objRS.ActiveConnection = objConnection
objRS.CursorType = 0 ‘adOpenForwardOnly
objRS.LockType = 1 ‘adLockReadOnly
objRS.Open Application(“SQL”)

If objRS.EOF Then
Response.Write “Não Foraam Encontrados Registros”
Else
‘Escreve o Conteúdo
...
End If

objRS.Close
Set objRS = Nothing
Next
objConn.Close
Set objConn = Nothing
...

Conclusão

O ganho de performance de cada um dos itens abordados pode não ser significante quando
vistos isoladamente. Mas o uso conjunto dessas dicas pode trazer um aumento expressivo na
performance de suas aplicações ASP.

Lições Aprendidas
• Não utilizar ADO ou qualquer outro tipo de Conexão (Tratamento de Dados)
diretamente das páginas (Camada de Apresentação)
• Construir o mais tarde e Destruir o mais cedo possível todo tipo de objeto
• Não utilizar-se de variáveis do Tipo Session
• Não requerer transações diretamente das páginas
• Forçar Option Explicit em páginas e classes
• Para listagem com mais de 200 registros: Utilizar paginação (vide MSDN – utilização
de GetRows)
• Não utilizar On error Resume Next
• Desabilitar Bufferização, apenas quando utilizar um processo muito longo com
necessidade de visualização.
• Não utilizar de arquivos .inc
• Evitar utilização de retornos de funções com ADO Objects – Sempre que possível
utilizar-se de GetRows)
• Para conexões com o Oracle , utilizar o provider Microsoft (OLEDB)
• Não utilizar-se de arquivos .INI
• Não Utilizar upload e Download de arquivos com utilização diretamente do diretório
do Servidor
• Não fazer uso de variáveis públicas em módulos
• Sempre em DLL´s valer-se do tratamento de Erro
• Ser compatível com O Explorer e o Netscape verão 4 ou posterior.
• Em Caso da Utilização de applets ou componentes/API’S, apresentar o código fonte
ou certificado de suporte e manutenção garantidos pelo fabricante.
• Todas as aplicações devem possuir Data, Hora, Moeda e Code Page em formato
Americano.
• Utilizar Resolução de 800 x 600 256 cores.
• Não utilizar variáveis de DSN como ORA, DB2, PROD etc.. Exemplo: Aplicação +
Tipo de Base . CGI_ORA.
• Utilizar para fluxo de dados procedures no Oracle ou Transações no IBM, disparando-
os por objetos de negócio.
• Não Utilizar SQL ou Algoritmos na camada de interface (ASP).
• Garantir que todos os Objetos/API´s ou Serviços do Servidor serão startados
automaticamente após um boot do servidor.
• Não utilizar IP’s Fixos ou Explícitos. Somente Labels fornecidos pelo Suporte
obedecendo o padrão de DNS.

Introdução ao Windows DNA

Introdução ao Projeto e Construção de Aplicações Windows DNA

Para projetar e construir aplicações de três camadas para a plataforma Microsoft®


Windows®, os desenvolvedores devem entender duas coisas: os fundamentos do projeto de
aplicação de três camadas em geral e as tecnologias Microsoft específicas que são relevantes
para o desenvolvimento de aplicações de três camadas para a plataforma Windows. O
Windows DNA descreve os dois requisitos. O Windows Distributed interNet Application
(DNA) é uma arquitetura genérica que descreve como construir aplicações de três camadas
para a plataforma Windows. O propósito desta introdução é proporcionar aos desenvolvedores
uma metodologia genérica para projetar e construir aplicações Windows DNA. Esta
introdução não tentará descrever cada aspecto concebível do Windows DNA, ao invés disto se
concentrará em proporcionar ao leitor um entendimento profundo das doutrinas básicas do
projeto de aplicação Windows DNA.

Obs: Uma aplicação de três camadas é uma aplicação cuja funcionalidade pode ser
segmentada em três camadas lógicas de funcionalidade: serviços de apresentação, serviços de
negócio e serviços de dados.

A camada de serviços de apresentação é responsável por:

• Obter informação do usuário.

• Enviar a informação do usuário para os serviços de negócio para processamento.

• Receber os resultados do processamento dos serviços de negócio.

• Apresentar estes resultados para o usuário.

A camada de serviços de negócio é responsável por:

• Receber input da camada de apresentação.

• Interagir com os serviços de dados para efetuar as operações de negócio que a


aplicação foi projetada para automatizar (por exemplo, preparação de imposto de renda,
processamento de pedido e assim por diante).

• Enviar os resultados processados para a camada de apresentação.

A camada de serviços de dados é responsável pelo(a):

• Armazenamento dos dados.

• Recuperação dos dados.

• Manutenção dos dados.

• Integridade dos dados.

Os serviços de dados vêm em uma variedade de formatos e tamanhos, incluindo sistemas de


gerenciamento de bancos de dados relacionais (RDBMSs) como o Microsoft SQL Server™,
servidores de e-mail como o Microsoft Exchange Server e sistemas de arquivo como o NTFS
File System.
Em contraste, uma aplicação de duas camadas é uma aplicação cuja funcionalidade somente
pode ser segmentada em duas camadas lógicas, serviços de apresentação e serviços de dados,
e embora as responsabilidades dos serviços de dados sejam as mesmas para sistemas de duas e
de três camadas, as responsabilidades dos serviços de apresentação não são. Em uma
aplicação de três camadas, os serviços de apresentação são responsáveis por obter informação
do usuário, enviar a informação do usuário para os serviços de negócio para processamento,
receber os resultados do processamento dos serviços de negócio e apresentar estes resultados
para o usuário. Entretanto, os serviços de apresentação de uma aplicação de duas camadas são
levemente diferentes. Os serviços de apresentação de uma aplicação de duas camadas são
responsáveis por obter informação do usuário, interagir com os serviços de dados para efetuar
as operações de negócio da aplicação e apresentar os resultados destas operações para o
usuário.

Obs: Uma aplicação de duas camadas é uma aplicação cuja funcionalidade somente pode ser
segmentada em duas camadas lógicas de funcionalidade: serviços de apresentação e serviços
de dados.

As diferenças nas responsabilidades dos serviços de apresentação para aplicações de duas e de


três camadas influenciam bastante a perspectiva do desenvolvedor da aplicação como um
todo. Por exemplo, em um projeto de duas camadas a lógica que efetua as tarefas para qual a
aplicação está sendo projetada para automatizar (por exemplo, preparação de imposto de
renda, processamento de pedido e assim por diante), que é comumente vista como "a
aplicação", é executada onde quer que o serviço de apresentação esteja localizado. Entretanto,
em um projeto de três camadas "a aplicação" é executada onde quer que os serviços de
negócio estejam localizados. Tais diferenças fundamentais podem levar a todos os tipos de
confusão na discussão dos conceitos de aplicação de três camadas com desenvolvedores de
aplicação de duas camadas ou vice versa, e é por isso que é crucial entender a diferença
fundamental na perspectiva do desenvolvedor associada com projetos de aplicação de duas e
três camadas.
Exemplos de Código

Componentes de Acesso à Base de Dados (Data Base Services)

'***************************************************************************
*************
'* Referência: Microsoft ActiveX Data Objects 2.6 Library *
'* COM+ Services Type Library - comsvs.dll *
'***************************************************************************
*************
Option Explicit

'Este método deve ser usado também para Delete e Update quando não utilizam
'Stored Procedures e não retornam nenhum valor
Public Sub Insert()

Dim vSql As String


Dim vCn As ADODB.Connection

On Error GoTo ErrorHandler

vSql = "INSERT INTO ..."

Set vCn = New ADODB.Connection

vCn.CursorLocation = adUseClient
1000 vCn.Open ReadDSN
1100 vCn.Execute vSql, , adExecuteNoRecords

1200 vCn.Close

Set vCn = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vCn Is Nothing Then


Set vCn = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Sub

'Este método deve ser usado também para Insert e Delete quando não utilizam
'Stored Procedures, mas retornam o número de linhas afetadas
Public Function Update() As Long

Dim vSql As String


Dim vCn As ADODB.Connection

On Error GoTo ErrorHandler

vSql = "UPDATE ..."

Set vCn = New ADODB.Connection

vCn.CursorLocation = adUseClient
1000 vCn.Open ReadDSN
1100 vCn.Execute vSql, Update

1200 vCn.Close

Set vCn = Nothing

GetObjectContext.SetComplete
Exit Function

ErrorHandler:

If Not vCn Is Nothing Then


Set vCn = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function
'Este método deve ser usado também para Insert e Update quando utilizam
'Stored Procedures e não retornam nenhum valor
Public Sub Delete(ByVal pParam1 As Long, ByVal pParam2 As String)

Dim vCn As ADODB.Connection


Dim vCmd As ADODB.Command

On Error GoTo ErrorHandler

Set vCn = New ADODB.Connection


Set vCmd = New ADODB.Command

vCn.CursorLocation = adUseClient
1000 vCn.Open ReadDSN

Set vCmd.ActiveConnection = vCn

vCmd.CommandText = "..."
vCmd.CommandType = adCmdStoredProc

1100 vCmd.Parameters.Append vCmd.CreateParameter(, adDouble, adParamInput, ,


pParam1)
1200 vCmd.Parameters.Append vCmd.CreateParameter(, adVarChar, adParamInput, 20,
pParam2)

1300 vCmd.Execute

1400 vCn.Close

Set vCmd.ActiveConnection = Nothing


Set vCmd = Nothing
Set vCn = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vCn Is Nothing Then


Set vCn = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Sub
'Este método deve ser usado para retornar um recordset desconectado
Public Function SelectAll() As ADODB.Recordset

Dim vSql As String


Dim vCn As ADODB.Connection
Dim vRs As ADODB.Recordset

On Error GoTo ErrorHandler

vSql = "SELECT * FROM ..."

Set vCn = New ADODB.Connection


Set vRs = New ADODB.Recordset

vCn.CursorLocation = adUseClient
1000 vCn.Open ReadDSN

vRs.CursorLocation = adUseClient
Set vRs.ActiveConnection = vCn
1100 vRs.Open vSql, , adOpenForwardOnly, adLockReadOnly, adCmdText

Set vRs.ActiveConnection = Nothing

1200 Set SelectAll = vRs

1300 vCn.Close

Set vRs = Nothing


Set vCn = Nothing
GetObjectContext.SetComplete
Exit Function

ErrorHandler:

If Not vRs Is Nothing Then


If Not vRs.ActiveConnection Is Nothing Then
Set vRs.ActiveConnection = Nothing
End If
Set vRs = Nothing
End If
If Not vCn Is Nothing Then
Set vCn = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function

'Este método deve ser usado para realizar a paginação de um recordset


'ele retorna um array bi-dimensional contendo os registros do recordset
Public Function SelectArray(ByVal pPage As Long, ByVal pQtde As Long) As Variant

Dim vSql As String


Dim vCn As ADODB.Connection
Dim vRs As ADODB.Recordset

On Error GoTo ErrorHandler

vSql = "SELECT * FROM ..."


Set vCn = New ADODB.Connection
Set vRs = New ADODB.Recordset

vCn.CursorLocation = adUseServer
1000 vCn.Open ReadDSN

vRs.CursorLocation = adUseServer
Set vRs.ActiveConnection = vCn
1100 vRs.Open vSql, , adOpenForwardOnly, adLockReadOnly, adCmdText

If Not vRs.EOF Then


1200 vRs.Move (pPage - 1)
If Not vRs.EOF Then
1300 SelectArray = vRs.GetRows(pQtde)
End If
End If

1400 vRs.Close
1500 vCn.Close

Set vRs.ActiveConnection = Nothing


Set vRs = Nothing
Set vCn = Nothing

GetObjectContext.SetComplete
Exit Function

ErrorHandler:

If Not vRs Is Nothing Then


If Not vRs.ActiveConnection Is Nothing Then
Set vRs.ActiveConnection = Nothing
End If
Set vRs = Nothing
End If
If Not vCn Is Nothing Then
Set vCn = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function
'Este método deve ser usado para retornar um recordset no formato de string
Public Function SelectString() As String

Dim vSql As String


Dim vCn As ADODB.Connection
Dim vRs As ADODB.Recordset

On Error GoTo ErrorHandler

vSql = "SELECT * FROM ..."

Set vCn = New ADODB.Connection


Set vRs = New ADODB.Recordset

vCn.CursorLocation = adUseServer
1000 vCn.Open ReadDSN

vRs.CursorLocation = adUseServer
Set vRs.ActiveConnection = vCn
1100 vRs.Open vSql, , adOpenForwardOnly, adLockReadOnly, adCmdText

1200 SelectString = vRs.GetString(adClipString, , "-", ";")

1300 vRs.Close
1400 vCn.Close

Set vRs.ActiveConnection = Nothing


Set vRs = Nothing
Set vCn = Nothing

GetObjectContext.SetComplete
Exit Function

ErrorHandler:

If Not vRs Is Nothing Then


If Not vRs.ActiveConnection Is Nothing Then
Set vRs.ActiveConnection = Nothing
End If
Set vRs = Nothing
End If
If Not vCn Is Nothing Then
Set vCn = Nothing
End If
GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function

'Este método deve ser usado para retornar a quantidade de registros


'de um recordset desconectado
Public Function Count() As Long
Dim vSql As String
Dim vCn As ADODB.Connection
Dim vRs As ADODB.Recordset

On Error GoTo ErrorHandler

vSql = "SELECT COUNT(1) FROM ..."

Set vCn = New ADODB.Connection


Set vRs = New ADODB.Recordset

vCn.CursorLocation = adUseClient
1000 vCn.Open ReadDSN

vRs.CursorLocation = adUseClient
Set vRs.ActiveConnection = vCn
1100 vRs.Open vSql, , adOpenForwardOnly, adLockReadOnly, adCmdText

Set vRs.ActiveConnection = Nothing

1200 Count = vRs(0)

1300 vRs.Close
1400 vCn.Close
Set vRs = Nothing
Set vCn = Nothing

GetObjectContext.SetComplete
Exit Function

ErrorHandler:

If Not vRs Is Nothing Then


If Not vRs.ActiveConnection Is Nothing Then
Set vRs.ActiveConnection = Nothing
End If
Set vRs = Nothing
End If
If Not vCn Is Nothing Then
Set vCn = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function

Private Function ReadDSN() As String


'***************************************************************************
*************
'* Objetivo: Montar a string de conexão com o banco de dados ORACLE
'* Retorno: String de conexão
'***************************************************************************
*************

Dim vConnect As String


Dim vLocal As String
Dim vComplement As String
Dim vDsn As String

vConnect = "sww_user"
vLocal = "ts01"
vComplement = "sww"

vDsn = "Provider=MSDAORA.1;Password=" & vComplement & ";User ID=" & vConnect


&_
";Data Source=" & vLocal & ";Persist Security Info=True"

ReadDSN = vDsn

End Function
Componentes de Negócios (Business Services)

'***************************************************************************
*************
'* Referência: Microsoft ActiveX Data Objects 2.6 Library *
'* COM+ Services Type Library - comsvs.dll *
'***************************************************************************
*************
Option Explicit

'Este método deve ser usado também para Delete e Update quando não utilizam
'Stored Procedures e não retornam nenhum valor
Public Sub Insert()

Dim vObj As DB.clsDB

On Error GoTo ErrorHandler

1000 Set vObj = New DB.clsDB

2000 Call vObj.Insert

Set vObj = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vObj Is Nothing Then


Set vObj = Nothing
End If
GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Sub

'Este método deve ser usado também para Insert e Delete quando não utilizam
'Stored Procedures, mas retornam o número de linhas afetadas
Public Function Update() As Long

Dim vObj As DB.clsDB

On Error GoTo ErrorHandler

1000 Set vObj = New DB.clsDB

2000 Update = vObj.Update()

Set vObj = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:
If Not vObj Is Nothing Then
Set vObj = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function
'Este método deve ser usado também para Insert e Update quando utilizam
'Stored Procedures e não retornam nenhum valor
Public Sub Delete(ByVal pParam1 As Long, ByVal pParam2 As String)

Dim vObj As DB.clsDB

On Error GoTo ErrorHandler

1000 Set vObj = New DB.clsDB

2000 Call vObj.Delete(pParam1, pParam2)

Set vObj = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vObj Is Nothing Then


Set vObj = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Sub

'Este método deve ser usado para retornar um recordset desconectado


Public Function SelectAll() As ADODB.Recordset

Dim vObj As DB.clsDB

On Error GoTo ErrorHandler

1000 Set vObj = New DB.clsDB

2000 Set SelectAll = vObj.SelectAll()

Set vObj = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vObj Is Nothing Then


Set vObj = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function

'Este método deve ser usado para realizar a paginação de um recordset


'ele retorna um array bi-dimensional contendo os registros do recordset
Public Function SelectArray(ByVal pPage As Long, ByVal pQtde As Long) As Variant

Dim vObj As DB.clsDB

On Error GoTo ErrorHandler


1000 Set vObj = New DB.clsDB

2000 SelectArray = vObj.SelectArray(pPage, pQtde)

Set vObj = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vObj Is Nothing Then


Set vObj = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function

'Este método deve ser usado para retornar um recordset no formato de string
Public Function SelectString() As String

Dim vObj As DB.clsDB

On Error GoTo ErrorHandler

1000 Set vObj = New DB.clsDB

2000 SelectString = vObj.SelectString()

Set vObj = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vObj Is Nothing Then


Set vObj = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description
End Function

'Este método deve ser usado para retornar a quantidade de registros


'de um recordset desconectado
Public Function Count() As Long

Dim vObj As DB.clsDB

On Error GoTo ErrorHandler

1000 Set vObj = New DB.clsDB

2000 Count = vObj.Count()

Set vObj = Nothing

GetObjectContext.SetComplete
Exit Sub

ErrorHandler:

If Not vObj Is Nothing Then


Set vObj = Nothing
End If

GetObjectContext.SetAbort
App.LogEvent "Componente.Classe.Metodo" & " [" & Err.Number & "] - " & _
Err.Description & " line " & Erl
Err.Raise Err.Number, Err.Source, Err.Description

End Function

Você também pode gostar