OOP no Visual Basic

Embora este não seja um artigo extenso e ocupe uma pequena parte no conjunto das informações que lhe estão sendo enviadas neste CD, considero-o especialmente interessante na medida em que pode significar uma contribuição para a padronização de suas aplicações. O tratamento do assunto não se esgotará aqui, mas será continuado nas atualizações futuras a este pacote de Visual Basic. Você poderá acessar essas atualizações com sua senha de acesso à nossa página na Internet . O tema a ser tratado aqui é a orientação a objeto, uma abordagem relativamente nova no desenvolvimento de sistemas para fins comerciais e que tem se tornado o tema do momento quando se fala em metodologia de trabalho na área de sistemas informatizados. Não pretendo fazer uma grande explanação sobre a OOP, mas apenas introduzirei as idéias básicas da OOP para, em seguida, apresentar uma forma que considero racional de organizar uma aplicação em Visual Basic explorando os seus modernos recursos de orientação a objeto. O modelo que discutirei está baseado na arquitetura documento-vista, já velha conhecida dos programadores de C++ que utilizam a biblioteca de classes de fundamentos da Microsoft (MFC). No meio dos programadores em Visual Basic, no entanto, este assunto é pouco conhecido.

O que significa "Baseado em Objetos"?

Sob um ponto de vista superficial, a expressão "baseado em objetos" significa que o software é organizado como uma coleção de objetos separados que incorporam tanto a estrutura como o comportamento dos dados. Isto contrasta com a programação convencional, segundo a qual a estrutura e o comportamento dos dados têm pouca vinculação entre si. Existe alguma discordância sobre quais são exatamente as características exigidas pela abordagem baseada em objetos, mas geralmente elas incluem quatro aspectos: identidade, classificação, polimorfismo e herança.

Características dos Objetos

Identidade significa que os dados são subdivididos em entidades discretas e distintas, denominadas objetos. Um parágrafo em um documento, uma janela na minha estação de trabalho e a rainha branca no jogo de xadrez são exemplos de objetos. Os objetos podem ser concretos, como um arquivo em um sistema de arquivos, ou conceituais, como uma norma de escalonamento em um sistema operacional de multiprocessamento ou uma operação em um programa. Cada objeto tem sua própria identidade, que lhe é inerente. Em outras palavras, dois objetos são distintos mesmo que todos os valores de seus atributos (como nome e tamanho) sejam idênticos.

No mundo real um objeto limita-se a existir, mas, no que se refere a uma linguagem de programação, cada objeto dispõe de um único indicador, pelo qual ele pode ser referenciado inequivocamente. O indicador pode ser implementado de diversas maneiras, como um endereço na memória, um elemento de uma matriz ou um valor exclusivo de um atributo. As referências dos objetos são uniformes e independentes do conteúdo dos mesmos, permitindo a criação de objetos mesclados, tal como um diretório de um sistema de arquivos que contenha tanto arquivos como subdiretórios.

Classificação significa que os objetos com a mesma estrutura de dados (atributos) e o mesmo comportamento (operações) são agrupados em uma classe. Parágrafo, Janela e Peça de Xadrez são exemplos de classes. Uma classe é uma abstração que descreve propriedades importantes para uma aplicação e ignora o restante. Qualquer escolha de classes é arbitrária e depende da aplicação.

Cada classe descreve um conjunto possivelmente infinito de objetos individuais. Cada objeto é dito ser uma instância de sua classe. Cada instância da classe tem seu próprio valor para cada atributo, mas compartilha os nomes de atributos e operações com as demais instâncias da mesma classe. Um objeto contém uma referência implícita à sua própria classe; ele "sabe que tipo de coisa ele é".

Polimorfismo significa que a mesma operação pode atuar de modos diversos em classes diferentes. A operação move (mover), por exemplo, pode atuar de modo diferente nas classes Janela e Peça de Xadrez. Uma operação é uma ação ou transformação que um objeto executa ou a que ele está sujeito. Right-justify (justificar à direita), display (exibir) e move (mover) são exemplos de operações. Uma implementação específica de uma operação por uma determinada classe é chamada de método. Como uma operação baseada em objetos é polimórfica, pode haver mais de um método para a sua implementação.

No mundo real uma operação é simplesmente uma abstração de um comportamento análogo entre diferentes tipos de objetos. Cada objeto "sabe como" executar suas próprias operações. Entretanto, uma linguagem de programação baseada em objetos seleciona automaticamente o método correto para implementar uma operação com base no nome da operação e na classe do objeto que esteja sendo operado. O usuário de uma operação não precisa saber quantos métodos existem para implementar uma determinada operação polimórfica. Novas classes podem ser adicionadas sem que se modifique o código existente, são fornecidos métodos para cada operação aplicável nas novas classes.

Herança é o compartilhamento de atributos e operações entre classes com base num relacionamento hierárquico. Uma classe pode ser definida de forma abrangente e depois ser refinada em sucessivas subclasses mais definidas. Cada subclasse incorpora, ou herda, todas as propriedades da sua superclasse e acrescenta suas próprias e exclusivas características. As propriedades da superclasse não precisam ser repetidas em cada subclasse. Por exemplo, Janela Rolante e Janela Fixa são subclasses da superclasse Janela. Estas duas subclasses herdam as propriedades de Janela, como uma região visível na tela. Janela Rolante acrescenta uma barra de rolagem e limites de rolagem. A capacidade de identificar propriedades comuns a várias classes de uma superclasse comum e de fazê-las herdar as propriedades da superclasse pode reduzir substancialmente as repetições nos projetos e programas e é uma das principais vantagens dos sistemas baseados em objetos.

O Visual Basic e a OOP

A partir da versão 4, o Visual Basic teve um importante acréscimo à sua massa de recursos: as classes. Podendo criar suas próprias classes, os programadores em Visual Basic passaram ter como organizar suas aplicações dentro de uma ótica de programação orientada para objetos. O problema agora passa a ser "o que fazer para tirar o máximo de proveito deste novo recurso?". Acredito que uma das fontes de resposta a esta pergunta pode ser buscada nas práticas de programação em linguagens orientadas a objeto mais tradicionais, como a C++. Por esta razão decidi examinar a já conhecida arquitetura documento-vista, sobre a qual está baseada a biblioteca de classes de fundamentos (MFC) que acompanha o Visual C++. Nem tudo pode ser transposto para o Visual Basic, mas ainda assim acredito que os ganhos em estruturação e racionalidade para as aplicações é compensador.

A arquitetura documento-vista, como o próprio nome já diz, está fundamentada na relação entre um documento e sua(s) vista(s). Por documento entenda-se um conjunto de informações gravadas em disco e que podem ser tomadas como uma unidade a ser apresentada. Por exemplo, um arquivo de texto pode ser tratado como um documento, mas uma tabela dentro de um banco de dados Access também pode ser tratada como um documento já que pode ser tomada como uma unidade a ser apresentada.

Nessa relação o documento é representado pela classe - CDocument - que contém toda a funcionalidade para centralizar o controle das diferentes formas da apresentação dos dados. As diferentes formas de apresentação de um documento correspondem às suas vistas, e estas são construídas a partir da classe CView. Cabe à classe CDocument manter uma coleção das suas vistas a cada momento. Quando uma vista é usada para modificar os dados em disco, a classe CDocument é informada pela vista da modificação e, se for o caso, pode ser solicitada a comunicar todas as demais vistas para que se atualizem. Quando uma vista é fechada, antes de encerrar sua atividade, ela comunica a classe CDocument para que faça a sua remoção da coleção de vistas.

Cabe à vista todo o trabalho de interação com o usuário seja na apresentação dos dados na tela, seja na remessa de informações do documento para a impressora. Cada vista do documento é um formulário com um conjunto de métodos de uso comum, tais como: localizar, substituir, copiar, colar, imprimir, visualizar impressão. Para cada vista estes métodos serão implementados de uma forma compatível com os dados que a vista apresenta e também com o formato dessa apresentação. O importante é que, sendo este conjunto de métodos nomeados de modo igual em todas as vistas, outros objetos não terão que se comportar de modo diferente nas suas relações com as vistas a cada vez que se modifique a vista ativa na aplicação. Por exemplo, a janela principal tem no menu Editar uma série de submenus que podem significar ações diferentes a serem tomadas dependendo de qual vista de um documento esteja ativa no momento. Copiar pode representar uma coisa se a vista ativa estiver exibindo uma tabela em formato de grade, mas pode significar outra coisa se o que estiver sendo exibindo for um gráfico baseado na tabela. Não cabe, portanto, à janela principal saber o que deve ser copiado, mas sim à vista ativa. Chamando o método copiar da vista, a janela principal lava as mãos e deixa à vista o trabalho de fazer a cópia do que deve ser copiado. O mesmo vale para o menu Localizar, por exemplo. Se uma vista exibe um documento tipo texto, a janela de localização é de um tipo, mas se o que está sendo exibido é um recordset, evidentemente que a janela a ser exibida é de outro tipo, com outra funcionalidade. Seguindo esta linha de divisão de responsabilidades, podemos levar nossas aplicações a um alto grau de reutilização de código e modularidade, além de torná-las mais rapidamente compreensíveis na medida em que seguem um padrão que se repete.

A arquitetura documento-vista não pode responder por toda uma aplicação. È apenas uma relação central em torno da qual gravitam outras classes que têm papel importante na estrutura da aplicação. Por exemplo, alguém tem que coordenar a criação e encerramento dos documentos. Este trabalho é feito por uma classe chamada CDocTemplate. DocTemplate é abreviatura para algo que, em português, seria "modelo de documento". Um modelo de documento reúne algumas informações importantes para a manipulação dos documentos de um determinado tipo. Como um conjunto de informações gravadas em disco, o documento pode precisar ser aberto como um arquivo. Isto exige a identificação do documento pela extensão presente no nome do arquivo. Dependendo da extensão no nome do arquivo, uma rotina diferente será chamada para abri-lo e uma vista apropriada será criada para exibi-lo. Quem faz este trabalho é a classe CDocTemplate. Para cada tipo de documento presente em uma aplicação, você deve providenciar um objeto da classe CDocTemplate inicializado com as informações necessárias para manipular aquele tipo de documento. Do mesmo modo que os objetos da classe CDocument mantêm uma coleção com referências às suas vistas de momento, os objetos CDocTemplate mantêm uma coleção de todos os objetos CDocument mantidos por eles a cada instante.

Os objetos CDocTemplates por sua vez, também precisam ser coordenados dentro da aplicação. Quem se incumbe desta tarefa é o objeto App. Não aquele que o Visual Basic lhe fornece, mas sim um que você cria para encapsular o objeto App do Visual Basic e acrescentar-lhe outros atributos e capacidades. O objeto App mantém uma coleção de todos os modelos de documentos presentes na aplicação. No momento em que o usuário clica sobre o menu Arquivo\Abrir, o objeto App é solicitado a percorrer essa coleção em busca de informações para a caixa de diálogo. Cada objeto CDocTemplate tem uma propriedade onde está armazenada uma string de filtro a ser usada na caixa de diálogo Abrir Arquivo. Antes que o objeto App mostre a caixa de diálogo Abrir Arquivo, ele coleta estas strings para compor o conjunto de filtros de arquivos que a caixa de diálogo deve possibilitar ao usuário abrir. O mesmo vale para o menu Arquivo\Novo.

Não estamos aqui nos aprofundando no assunto da forma devida, mas apenas dando uma idéia geral do que pode ser feito dentro dessa linha de raciocínio. Temos um exemplo da aplicação destas idéias no projeto que se encontra no arquivo mfcnovb.zip. Apesar de estar incompleto dá para ter uma idéia do que pode ser feito nesta linha.

 

Navegue pelo seu código como num navegador com RabJump