15 de março de 2009

Orientação a Eventos versus Orientação a Aspectos

Paradigma Orientado a Eventos
Diferentemente de paradigmas como Estruturado e Funcional, o paradigma Orientado a Eventos está mais para uma técnica de programação do que para um paradigma propriamente dito. A Wikipedia define este paradigma como aquele em que o fluxo do programa é determinado por eventos.

Nota: Entenda-se por evento, qualquer interação do usuário com o programa, como pressionar de alguma tecla ou movimentação no mouse, além de mensagens de outros programas ou threads.

A mesma fonte ainda define o paradigma como uma técnica de arquitetura onde a aplicação possui uma iteração principal, que possui duas áreas bem definidas: a detecção de eventos e o tratamento dos mesmos.

Para termos uma noção do que isto significa, tomemos o seguinte exemplo escrito em Python e PyGTK, que cria uma janela com um botão, que se fecha quando este botão é clicado.

#!/usr/bin/env python


"""Implements simple operations on PyGTK.

Hello World is a simple Python program which
uses PyGTK to show a window with a Hello World
button. This window closes when button is clicked.

It's an adaptation of the original code in 
PyGTK tutorial

"""


import pygtk
pygtk.require('2.0')
import gtk


class HelloWorld:
    
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        
        self.window.connect("delete_event", self.delete_event)
        self.window.connect("destroy", self.destroy)
        
        self.window.set_border_width(10)
        self.button = gtk.Button("Hello World")
        
        self.button.connect("clicked", self.hello, None)
        self.button.connect_object("clicked", gtk.Widget.destroy, self.window)
        
        self.window.add(self.button)
        
        self.button.show()
        self.window.show()

    def run(self):
        gtk.main()
    
    def destroy(self, widget, data=None):
        print "destroy signal occurred"
        gtk.main_quit()
    
    def delete_event(self, widget, event, data=None):
        print "delete event occurred"
        return False

    def hello(self, widget, data=None):
        print "Hello World"


# 
# Main
# 

if __name__ == "__main__":
    hello = HelloWorld()
    hello.run()
Listagem 1. Exemplo de código orientado a eventos.

Na listagem 1, temos como exemplo de loop principal, a função run(). Nas linhas 26, 27, 32 e 33, temos a ligação dos eventos (i.e., signals) com os seus respectivos tratadores (i.e., callbacks). Estes tratadores são definidos na forma de funções e quando um evento é detectado em um componente do programa, o mesmo procura no seu código pelo tratador específico daquele evento, redirecionando o fluxo de execução para o mesmo, caso exista. No caso, quando o botão for clicado, por exemplo, o fluxo de execução do programa será desviado para o método hello() (linha 32), que imprimirá uma mensagem na tela. Repare que este mesmo botão possui outro evento associado a ele (linha 33), que executa o método de destruição da janela. Assim, ao clicar no botão, uma mensagem é impressa e a janela se fecha.

Vantagem e Desvantagem
Uma vantagem da programação orientada a eventos é que o conceito de eventos facilita a criação e manipulação de interfaces gráficas para programas. A desvantagem é que o entendimento deste paradigma é complicado para iniciantes, pois a maioria está acostumada a programas sequenciais, com uma única entrada e uma única saída.

Programação Orientada a Aspectos
A Programação Orientada a Aspectos (POA) objetiva separar semanticamente o código, como forma de torná-lo mais legível e fácil de se manter que nos outros paradigmas. Ao se programar Orientado a Objetos, o programador tenta encapsular várias características comuns dentro de classes, que são instanciadas ao longo do programa, criando os objetos. Já na na POA, o objetivo é aglomerar essas chamadas, de forma com que todos os aspectos do programa sejam codificados juntos.

Este é um paradigma relativamente novo e os seus conceitos ainda não estão amadurecidos como os da OO, por exemplo. Por isso não há tanto suporte para ele quanto em outros paradigmas. Apesar disso, todas as fontes pesquisadas apontam que este paradigma está em pleno desenvolvimento e que seu futuro é promissor. A grande desvantagem apontada para este paradigma é a depuração do código, que segundo a Wikipedia é complicada. Já a vantagem é a organização do código, que facilita a manutenção do software.

A linguagem orientada a aspectos mais usada atualmente é a AspectJ, que foi criada pelo próprio desenvolvedor  do paradigma, Gregor Kiczales e sua equipe na Xerox PARC. Recomendo a leitura dos textos sobre o paradigma, na seção Leitura Recomendada, para mais detalhes sobre o assunto e exemplos de códigos e ferramentas para este tipo de programação.

Conclusão
Na Programação Orientada a Eventos (POE), o programador tem a preocupação de quando algo vai acontecer. Este acontecimento pode se dar a qualquer momento ou pode até não acontecer, mas o programa tem de estar preparado para ele. Para isso, existem os conceitos de signals e callbacks, que detectam o acontecimento de um evento e tomam as medidas necessárias para tratá-lo. Isto ajuda muito na confecção de interfaces gráficas, pois nunca se sabe qual será a ação do usuário, além de possibilitar que o programa torne-se mais flexível, adaptando-se à maioria dos usuários.

A POA apresenta um conceito relativamente novo e promissor para codificação de softwares, mas o preço dessa juventude é a falta de maturidade do paradigma e a falta de ferramentas (linguagens, componentes e IDEs).




Leitura Recomendada
  • Event-Driven Programming – Um bom tutorial em inglês
  • Wikipedia – Página da Wikipedia sobre o assunto, em inglês
  • Dextra – Entendendo a Programação Orientada a Aspectos
  • UFSC – Programação Orientada a Aspectos

Clube de Revista
  • Anterior – Paradigma Funcional
  • Próximo – ?

18 comentários:

  1. Grande zezim!

    O POE realmente é uma paradigma fácil de se entender e acredito que para iniciantes, depende da linguagem de programação. Se a linguagem beneficiar a criação de interfaces gráficas (e.g. Delphi), o iniciante sequer aprende sobre o mesmo, pois já esta tudo preparado, é só escolher a o evento e determinar a ação correspondente. Agora se for para elaboração partindo do zero, um iniciante ficará perdido com certeza.

    Com relação a POA (realmente é recomendável para o melhor entendimento as leituras sugeridas) achei mais um complemento de OO do que um paradigma propriamente dito, até onde eu vi de exemplos.
    Realmente há uma facilidade enorme com relação a manutenção dos sistema, mas li no artigo da Wikipédia que existe um aumento de recursos computacionais, o que ao meu ver é desvantagem grande, pois imagine fazer isto numa aplicação bancária (e.g. no ABN Anro Bank, Banco Real no Brasil). Outra grande desvantagem também foi comentada na Wikipédia, onde um programador tem que conhecer muito bem o código, pois a criação de um novo método com o mesmo nome de um 'advice'. Ou seja, em uma grande corporação, como o exemplo acima , Banco Real, ou deve seguir um padrão de nomenclaturas ou deve listar todos os nomes que não devem ser usados.
    Realmente este conceito de programação ainda é imaturo, vejo pontos falhos que precisam ser corrigidos, mas a idéia em si é muito boa, facilitará muito.

    Agora deixo uma questão que ainda não sei qual a melhor resposta: o que é melhor, pegar um código OO e inserir POA ou começar do zero combinando OO e POA? Tenho minhas dúvidas.

    Abraço! Excelente post!

    ResponderExcluir
  2. É importante colocar que a utilização de um paradigma não anula a utilização de outro. Como Fabricio citou a cima, é possível utilizar POO e POA de forma complementar, tanto que POA acaba se confundindo como uma extensão de POO. Entretanto, seria como dizer que POO é uma extensão da Programação Estruturada.

    Ainda não tive experiência profissional com POA, somente em estudos por conta própria. Seus benefícios, quando o paradigma é utilizado corretamente, são notáveis. Os "interesses entrecortantes", que podem ser vistos como forte acoplamentos que não são resolvidos pela POO, são resolvidos com POA.

    Recomendo um grupo de estudo que foi criado há um tempo, mas que anda um pouco inativo apesar de seus 50 membros: http://groups.google.com/group/aspectos/

    Até mais. E parabéns pelo post de qualidade.

    ResponderExcluir
  3. Salve, Fabrício!

    Ótimas questões que você apontou!

    Por experiência própria, eu achei o POE bastante confuso quando comecei, não pelo paradigma em si, mas pela forma como ele foi exposto. Simplesmente não me disseram que eu estava adentrando numa nova forma de programação. Jogaram aquilo pra mim e só. Eu vinha de desenvolvimento de interfaces em modo texto, interfaces essas que não tinham tanta sofisticação e flexibilidade como as do modo gráfico. No modo texto, você não costuma deixar muitas opções para o usuário e assim você tem um controle maior sobre o caminho do usuário no programa. Normalmente há só um caminho pra sair ou acessar determinada função e isso facilita o trabalho do programador. Já pelo lado do usuário, isso costuma implicar em um programa mais difícil de se utilizar e menos amigável. No exemplo citado, do Hello World, você pode fechar o programa por, pelo menos, duas formas diferentes, uma pelo botão Hello World e outra pelo X da janela (e este é apenas um exemplo simples!).

    Por isso os conceitos do POE são interessantes. Um loop principal, signals e callbacks ajudam a manipular essas entradas de forma mais fácil. Eu vejo programas gráficos como uma pessoa no meio do tiroteio. Uma bala (signal) pode vir de qualquer lado e você (programador) tem que estar preparado (callback) pra ela.

    Eu vejo o Delphi como um ótimo software. Mas tenho pavor da linguagem Object Pascal e do fato de ser um software Only for Windows. Isso já é o bastante para eu não usá-lo e não indicar o seu uso pra qualquer pessoa. Acho que colaborou para essa aversão o fato de ter sido esta ferramenta onde eu dei os primeiros passos na POE, que não foram tão bons.

    Sobre a POA, eu achei bastante complicado encontrar algo concreto sobre o tema. Creio que isso reforça a tese da falta de maturidade do paradigma. De qualquer forma, todas as fontes pesquisadas apontaram o POA como um paradigma que é muito promissor, pois se evoluir como se espera, tende a trazer ótimos resultados para seus utilizadores.

    Com relação ao desempenho dos programas neste paradigma, a história mostra que não se pode ter tudo e algumas coisas melhoram em detrimento de outras. Cabe ao utilizador pesar se vale a pena usar aquela ferramenta, com as suas limitações. O que quero dizer é que mesmo com o paradigma OO "bombando", ainda há muitas aplicações que são feitas usando o paradigma estruturado ou mesmo o imperativo, isto pois há certas aplicações que não podem se dar ao luxo de usar muita memória ou necessitam de um processamento mais rápido. Imagino que a POA será usada em aplicações específicas, onde esta questão de memória e desempenho não seja tão crucial, apesar do hardware vir se desenvolvendo rápido, o que tende a atenuar este problema.

    Boa observação sobre os advices. Faltou isso no texto!

    Já sobre o método de desenvolvimento, uma das fontes que eu pesquisei, não me lembro ao certo qual, apontou como ponto fraco da POA, a falta de uma metodologia de desenvolvimento. Isso se deve ao fato do paradigma ser relativamente novo, além de não ser tão usado como a POO. Com menos utilizadores, a tendência é que haja menos interesse no assunto, mas com o tempo, segundo minhas pesquisas, isso deve mudar.

    Abraço!

    ResponderExcluir
  4. Salve, Cássio!

    Boa colocação! Grande exemplo disso é Python, onde pode-se programar estruturadamente, OO e funcionalmente, tudo no mesmo código. Esse link que você passou também é sensacional! É de grande ajuda para quem procura aprender mais sobre o assunto!

    Obrigado por compartilhar!
    Abraço!

    ResponderExcluir
  5. Fala Zé!

    Inicialmente gostaria de parabenizá-lo pela postagem, ficou bem estruturada.

    Como já discutido em outras situações a OO, a grosso modo, seria uma evolução do paradigma imperativo. Vejo o POA uma evolução da OO, pode-se tratar os aspectos como regras de negócios mantendo ainda assim o encapsulamento sem a necessidade de mexer em nada na estrutura de uma dada classe.

    Toda ferramenta que auxilia o desenvonvilmento de um sistema deve-se ser levado em consideração porque nos dias atuais não restam espaço para perda de tempo no mercado.

    Concordo que muitas vezes programa-se utilizando o conceito de eventos sem saber como funciona, i.e., sabe-se apenas mexer na ferramenta.

    Nos dias atuais é impossível, ao meu ver, desmembrar paradigmas e linguagens, em qualquer sistema seja de que tamanho for.

    Abraço.

    ResponderExcluir
  6. Poxa, e eu achando que a postagem tinha ficado orientada a objetos... ;-)

    Concordo sobre a visão do POA como evolução do POO.

    Sobre ser impossível desmembrar paradigmas e linguagens, eu acredito que não. É possível desmembrá-los, principalmente no caso de linguagens (não dá pra misturar Python e Ruby, por exemplo). Nestes dois casos eu creio que, assim como o Cássio deixou evidente, é possível combinar dois paradigmas e eu estendo isso pra linguagens, pois no caso do exemplo do Hello World deste post, estão combinados os paradigmas OO e OE e as linguagens Python e C (GTK é escrito em C e PyGTK é um binding para acessar a biblioteca usando Python). Contudo, apesar dessa combinação, fica bem definido que se está usando POE (um loop principal, signals e callbacks), POO (classes e objetos), Python (o código em si) e C (GTK).

    Sobre usar o conceito de eventos sem conhecê-lo, eu imagino que podemos usá-lo de certa forma sem conhecer seus conceitos, mas se não usarmos uma linguagem OA, é como programar OO em Assembly, ou seja, não estaremos programando realmente OA (principalmente se não conhecermos suas premissas).

    Inté! :-)

    ResponderExcluir
  7. Pode-se sim criar aplicações sem conhecer um dado paradigma.

    Quando me referir sobre misturar linguagens e paradigmas era por exemplo:

    Paradigmas: seu exemplo deixa claro isso, você misturou OO e OA.

    Linguagens: todo sistema, seja ela de que tamanho for, fará uso de pelo menos linguages declarativas, SQL ou XML.

    Estava pensando neste episódio qdo falei.

    Se for programar pra WEB então vira uma verdade salada.

    Kra, embora você tenha citado que foi difícil encontrar algo de concreto sobre Programação Orientada as Aspectos senti falta de um exemplo mais prático.

    Abraço bro!!!!

    ResponderExcluir
  8. > Paradigmas: seu exemplo deixa claro isso, você misturou OO e OA.
    No exemplo consta POO e POE. Recapitulando: OO = Orientação a Objetos; OE = Orientação a Eventos; e OA = Orientação a Aspectos. ;-)

    > Linguagens: todo sistema, seja ela de que tamanho for, fará uso de pelo menos linguages declarativas, SQL ou XML.
    Errado. Desse jeito ninguém programaria só em Pascal ou só em C ou só em Python ou só em Ruby. Generalizações normalmente conduzem a erros.

    Sobre a mistura, talvez você não tenha lido a minha resposta ao Cássio. O meu questionamento foi sobre a sua colocação que diz ser impossível desmembrar paradigmas e linguagens e eu mostrei que dá pra ver claramente onde uma linguagem ou paradigma está sendo usada.

    Na verdade, o fato de encontrar um bom conteúdo já é um motivo para a falta de exemplo (e foi pensando justamente nisso que eu justifiquei, tanto que todos os meus textos sobre o assunto contem exemplos). Contudo, eu deixei um gancho no texto para leitura de alguns links, onde pode-se encontrar exemplos, além do comentário do Cássio ter trazido um link bastante interessante (e com exemplos), pra quem se interessa sobre o assunto.

    Inté!

    ResponderExcluir
  9. "... Linguagens: todo sistema, seja ela de que tamanho for, fará uso de pelo menos linguages declarativas, SQL ou XML.
    Errado. Desse jeito ninguém programaria só em Pascal ou só em C ou só em Python ou só em Ruby. Generalizações normalmente conduzem a erro..."

    Não concordo mesmo com você. Qualquer desenvolvimento você mescla pelo menos a linguagem SQL para acesso a BD, visto que, o maior valor no mercado hoje é o dado(informação). Aplicações Desktop estão saindo mais e mais do mercado, o mesmo se volta completamente para Web ai então já era, virá uma bagunça.

    Claro que se sabe onde é empregada uma linguagem ou outra, mais nunca se desenvolve sobre uma única linguagem, a menos que não seja nada usual.

    Até mesmo o C que você citou usa disso, você pode incluir código Assembly que é uma linguagem de baixo nível.

    Python então kra, tem-se vários exemplos, Jython(java), XML(interface com o Glade), pg(SQL), não acontece nada sozinho.

    t+.

    ResponderExcluir
  10. @maurim http://vivaolinux.com.br/script/Analisador-Lexico-0.5
    Este link leva a um analisador léxico de uma linguagem do tipo Pascal, que eu fiz usando somente a linguagem C. Quer mais exemplos?

    Qualquer desenvolvimento você mescla pelo menos a linguagem SQL para acesso a BD [...]
    Generalizando de novo. Parece que você nunca programou em Pascal sem usar SQL...

    Inté.

    ResponderExcluir
  11. Também concordo que é possível programar em uma só linguagem, um exemplo básico são aqueles programas que implementamos (programa que calcula a área do triângulo, quadrado, retângulo, ...) quando estamos dandos os primeiros passos nesse campo, pelo menos eu comecei com Pascal desta forma. Outro exemplo (zezim pode confirmar) é um programa que implementei para executar arquivos e programas como outro usuário no Windows usando as contas locais ou de dominio. Implementei utilizando somente Delphi.
    Claro que se formos pensar em aplicações um pouco maiores e que exigem fluxo de dados necessitaremos de um banco de dados, aí sim teremos mais de uma linguagem.

    ResponderExcluir
  12. @Fabrício Só um detalhe do chato aqui: Delphi é a IDE. Object Pascal é a linguagem! ;-) Você captou onde eu queria chegar, quando insisti no problema de generalizações do Zé Mauro. Dizer que qualquer desenvolvimento de sistema utilizará SQL é um erro bizarro. Note que a mesma frase poderia ser validada com algo como "o desenvolvimento de qualquer software de grande porte, que necessite armazenar um volume considerável de dados, utilizará SQL", sendo que mesmo assim o software poderia ser construído sem SQL, o que não é usual, mas é possível. É preciso ter muito cuidado ao fazer esse tipo de afirmação, pois é fácil demais cair no erro. Por isso é preciso estar bem embasado.

    Inté!

    ResponderExcluir
  13. SQL é o exemplo mais usual. O que você disse com a programação Web, onde o tempo todo é feito serialização em XML. Ou até mesmo seu uso em Python.

    É minha opinião, não se faz nada, ao não ser muito específico, utilizando uma única linguagem.

    Claro que já utilizei em Pascal ou C, mais somente com objetivos acadêmicos. O mercado é uma salada de linguagens.

    Só como exemplo, teremos que implementar um WebService, o mesmo será em Java, mais o acesso a ele é em .NET(C#), sem contar o acesso a banco SQL e a serialização dos objetos XML ou WSDL. E sem contar que na aplicação ainda tem-se ASP e JavaScript.

    É uma merda kra, ao meu ver, no mercado é impossível desmembrar.

    t+

    ResponderExcluir
  14. Perdão, realmente viajei, isto é que dá querer fazer 20 coisas ao mesmo tempo!

    ResponderExcluir
  15. http://cutephp.com/

    Deem uma olhada, não utiliza bancos de dados, apenas arquivos.

    ResponderExcluir
  16. Salve, Fabrício!
    Excelente exemplo esse! Casa direitinho com o que eu afirmei no meu comentário anterior.
    Abração!

    ResponderExcluir
  17. Como já disse, sou analfabyte na info, mas sempre fico encantada com seus textos, mesmo não compreendendo muito - até mesmo pela minha "leiguisse" no assunto. Mas adoro ler, e ler nunca matou ninguém... não que eu tenha "sabido"!

    desejo uma ótima semana pra ti!!! e ótimos textos também!!!!

    ResponderExcluir
  18. @Two Ways... Realmente, nunca ouvi falar de um caso de morte por overdose de leitura! Obrigado pelos elogios! Boa semana pra ti também! :-)

    ResponderExcluir