Alceu JuniorPublicado em 03/07/2008
r9 - 03 Jul 2008 - AlceuJunior
Artigo sobre como utilizar o padrão de projeto Model-View-Controller (MVC) com o toolkit WxPerl.
MVC significa Model, View, Controller. É um padrão de desenvolvimento para linguagens orientadas à objeto muito difundido para criar interfaces gráficas porque prega a separação de um aplicativo com interface gráfica em três partes: modelo, visão e controlador.
Fazendo uso desse conceito de separação, é fácil poder-se alterar qualquer uma das partes do aplicativo sem ter de alterar as demais. Basicamente, essas três partes conceituais tem as seguintes responsabilidades:
Essa é uma explicação muito resumida sobre esse padrão. Existe documentação farta na internet sobre o assunto (veja Referências para algumas), mas antes de prosseguir gostaria de deixar mais duas observações para o leitor:
WxPerl é um módulo de extensão que permite a criação de aplicações gráficas para Perl. Ela é um "embrulho" para o conjunto de ferramentas gráficas chamado WxWidgets, escrito originalmente para ser utilizado com C++, permitindo que código Perl possa ser facilmente escrito para usar as funcionalidades dessa biblioteca gráfica.
Uma das vantagens de se utilizar WxPerl ao invés de outras bibliotecas é a possibilidade de criar aplicações multiplaforma, já que o WxWidgets está disponível para vários sistemas operacionais e usa as bibliotecas gráficas do próprio sistema, permitindo que usa aplicação tenha a mesma aparência e usabilidade de aplicativos escritos especificamente para o mesmo sistema.
A desvantagem do WxPerl é a falta de documentação da mesma, mesmo considerando que o WxWidgets é bem documentado.
O WxPerl funciona basicamente da seguinte forma: o programador cria uma
(ou mais) janela(s) e dentro dessas definem os elementos que
irão constituir a interface gráfica: quadros
(frames), botões, campos para entrada de dados, etiquetas,
etc. Um frame deve extender a classe Wx::Frame
e é dentro
dele que serão definidos os elementos gráficos, como
botões.
O programador irá definir como o frame irá responder à interação do usuário com os elementos gráficos através do uso de eventos. Cada elemento gráfico do WxPerl irá possuir eventos pré-definidos e eventos não são nada mais do que funções. O que programador terá de fazer é relacionar um evento a chamada de uma função, por exemplo:
EVT_BUTTON(
$self,
$self->{salvar}->GetId(),
função_qualquer( parâmetro )
);
O evento EVT_BUTTON se aplica a todos os botões do frame
atual, portanto um dos parâmetros a serem passados para a
função é o número identificador (ID) do
botão que capturou o evento (um clique do mouse, por
exemplo). O último parâmetro é a chamada para
outra função definida (no exemplo,
função_qualquer
). Ainda é possível
definir uma função dentro do próprio
código, passando então uma referência como
parâmetro.
EVT_BUTTON(
$self,
$self->{salvar}->GetId(),
sub { # isso vai gerar algo no terminal!
warn "Exemplo de função";
}
);
O leitor atento vai perceber logo que o modelo de programação do WXPerl não auxilia muito na aplicação do padrão MVC, visto que o frame (Visão) terá que saber como alterar o Modelo e vice-versa. Com o tempo isso vai acabar gerando código difícil de manter.
Para facilitar a aplicação do padrão MVC com WxPerl eu optei por aplicar outro padrão de projeto conhecido como Observer. Esse padrão permite registrar a ocorrência de eventos e informar as classes interessadas nesses eventos, chamando um método das mesmas. Isso funciona num esquema muito parecido com o esquema "publicar e monitorar". O uso desse padrão permite separar o "publicador" do "monitorador", garantindo uma interface genérica para publicação e inscrição de eventos.
O padrão de projeto Observer tem uma implementação disponível para download no CPAN ( Class::Publisher) o que me poupou um bom trabalho.
Com certeza existem outras formas de utilizar MVC com WxPerl, mas na época que precisei escrever o aplicativo-exemplo mais abaixo, não existia uma maneira já definida pela distribuição do WxPerl.
Como exemplo de utilização, eu desenvolvi um aplicativo bastante simples que na realidade teve aplicação prática. Participei de um projeto de integração de sistemas e uma das responsabilidades da equipe era gerar documentação dos produtos desenvolvidos. Para esse tarefa um tanto ingrata arrumaram um trainee que não sabia absolutamente nada de SQL ou banco de dados relacional.
Como ele tinha que documentar interfaces de exportação de dados e o formato do arquivo e registros exportados, e as queries já estava todas prontas, eu desenvolvi esse aplicativo para gerar essa informação rapidamente para ele.
Basicamente, o aplicativo vai receber como entrada uma query e
à partir da mesma obter os metadados das colunas pesquisas no
banco, independente da quantidade de tabelas envolvidas na pesquisa.
Para fazer isso, o aplicativo vai usar uma função
disponível na biblioteca OBDC chamada DescribeCol
. Se a
implementação do banco de dados para ODBC for feita
corretamente, essa função permite obter
informações sobre o tipo de dado retornado por cada
coluna sem executar a query, o que é uma boa pedida se a
mesma tiver alto custo para ser executada no banco de dados.
Segue abaixo o diagrama UML das classes utilizadas no programa:
Diagrama_geral.png
A aplicação precisa de um arquivo INI para poder obter os dados necessários para se conectar via ODBC. Segue um exemplo de um arquivo INI:
[Siebel Tools]
DSN = data source name
user = usuário
password = senha
A seção "Siebel Tools" será exibida no menu "Conexões" da aplicação.
exemplo.png
Alceu Junior