domingo, 27 de novembro de 2011

Linguagens: baseada em objetos e orientada a objetos


Uma das tarefas mais importantes para os engenheiros/analistas/programadores de software é a escolha da linguagem que irão utilizar para realizar o trabalho da "melhor forma possível". Acho importante enfatizar a "melhor forma possível" com aspas, pois ela varia de acordo com uma série de parâmetros que geralmente estão ligados à época (arquitetura dominante, teoria e até modismo ...), filosofia da empresa e/ou do sistema, quesitos como performance, estabilidade, funcionalidade, segurança, user friendliness etc. Portanto, a "melhor forma possível" varia dependendo do referencial.
Dito isso, vou escrever um pouco sobre Programação Orientada a Objetos (OOP), que é provavelmente a principal razão pela qual estamos interessados em diferenciar linguagens baseadas em objetos e orientadas a objetos.
OOP é um paradigma (padrão a ser seguido) que utiliza objetos para construir programas de computador. Apesar de haver muita controvérsia sobre o assunto, muitas vezes a OOPestá relacionada à "melhor forma possível" de se programar, principalmente quando ela resulta de uma simples e coerente compreensão da realidade sob o ponto de vista da Análise Orientada a Objetos (OOA), tornando o Design Orientado a Objetos (OOD)consistente, o que, por fim, facilita a OOP, resultando em programas claros e fáceis de manter.

Entretanto, nem sempre uma modelagem da realidade pode ser expressa através de objetos, ou simplesmente talvez não seja a melhor forma de fazê-lo. Existem vários dilemas e casos onde, dependendo do que se busca, não vale a pena utilizar OO. Nesse ponto, não posso deixar de citar os artigos "Why OO Sucks" de Joe Armstrong, criador da linguagem Erlang; "Bad Engineering Properties of Object-Oriented Languages" de Luca Cardelli, principal pesquisador e líder dos grupos "Programming Principles and Tools" e "Security" na Microsoft Research em Cambridge; e o desabafo de Richard Stallman, criador do projeto GNU e fundador da Free Software Foundation, no Google Group comp.emacs.xemacs, que diz que "adicionar OOP no Emacs não é claramente uma melhoria; usei OOP quando trabalhava no sistema de janela da Lisp Machine e não concordo com a visão usual de que ela seja uma forma superior de se programar." (ver thread original "Mode inheritance, cloning, hooks & OOP").
Dado ests breve overview sobre OOP, seguirei o artigo escrevendo mais um pouco sobre objetos, OOAOOD e depois entrarei no tema principal que é "Linguagens: Baseada em Objetos e Orientada a Objetos", mas antes disso segue abaixo o lembrete que alguns já conhecem, mas outros não.
Para os que ainda não sabem, este é o quarto artigo de uma série que me comprometi a escrever para o iMasters. Segue abaixo a relação dos artigos:
  1. ASP, uma tecnologia mal interpretada.
  2. Programação orientada a eventos e lambda function em ASP/VBScript.
  3. TDD (Test Driven Development) em ASP/VBScript.
  4. Linguagens: Baseada em Objetos e Orientada a Objetos.
  5. Orientação a Objetos em VBScript "Hackers way".
  6. Scripting Components, os "Às" na manga.
  7. Caching, conceito de DRY(Don't Repeat Yourself) aplicado ao ASP.
Se você estiver lendo um artigo meu pela primeira vez, recomendo enfaticamente que leia os anteriores primeiro, pois estou tentando levá-los à compreensão de uma grande abstração, contando uma pequena parte da ideia por vez. Colocarei links para os temas anteriores para facilitar o acesso, mas utilizem CTRL+Click, pois não há links de um artigo para seus sucessores.

O que é um objeto?

Sinto um certo desconforto por ter utilizado demasiadamente o termo objeto sem antes assegurar uma noção do conceito ao leitor. Portanto, esta seção remedia a situação.
Existem várias definições para objeto, tais como a de Booch (1991), um dos criadores doUML:
"Um objeto tem um estado, comportamento e identidade; a estrutura e o comportamento de objetos semelhantes são definidos em sua classe comum; os termos instância e objetos são intercambiáveis".
Essa é uma definição muito restritiva que se aplica apenas a "linguagens orientadas a objetos clássicas" como Java, C#, C++ e outras em acordo com a definição de Coplien (1992) onde"classes desempenham um papel central na modelagem de objetos", uma vez que em linguagens de prototyping ou delegates elas não têm este papel. Há também definições mais abrangentes como a de Cox (1991), "quaquer coisa com uma fronteira razoavelmente (crisply) definida" que servem a um domínio mais amplo (extrapolam o mundo computacional), mas que, embora descreva objetos, também descreve ideias, distribuições etc.
Entretanto, essa é um boa definição quanto aumentada para um domínio específico. É o caso de Rumbaugh (1991):
"Nós definimos um objeto como um conceito, abstração ou coisa com uma fronteira razoavelmente (crisp) definida com significado para o problema em questão".
Quando isso ocorre, o desenvolvedor precisa parar, pensar, rever seus conceitos e decidir exatamente onde quer chegar antes de seguir adiante. No meu caso, gosto de buscar minhas inspirações na filosofia oriental. Veja abaixo uma citação de Confúcio:
"É por respeitar a natureza virtuosa que o homem verdadeiro dedica-se a aprender o Tao. Examinando em conjunto e por miúdo; do máximo da claridade encontra o caminho do meio. É por retomar os antigos que se descobre o novo e, com isto, honra os Ritos."
Na busca pelo caminho do meio em programação, não querendo ser genérico nem especializado demais, nem almejando uma guerra de chamas contra os antigos pela busca da definição ideal, utilizarei simplesmente uma versão atenuada de objetos derivada da definição de Booch mesclada à de Rumbaugh: "Um objeto é uma estrutura que possui estados, comportamentos, identidade e possui algum significado para o problema em questão", que é a de Booch (1991) sem as restrições e consequências relacionadas ao uso de classes, unida à de Rumbaugh (1991), trocando-se a parte de fronteira por estados e comportamentos. Essa definição é melhor nos dias atuais, pois engloba outros conceitos que surgiram para trabalhar com objetos que não o de classe.

OOA, OOD?

Apesar das raízes de objetos em computação datarem do final da década de cinquenta em trabalhos do grupo de inteligência artificial no MIT e, posteriormente, conceituados formalmente para programação com a introdução do Simula 67 na década de sessenta. Os temas OOA e OOD só se tornaram assuntos relevantes de pesquisa na década de noventa, quando a OOP se tornou a metodologia de programação dominante, possivelmente impulsionada pelo C++, Visual FoxPro 3.0 e pelo sucesso das interfaces de usuário gráficas, que são fortemente baseadas em técnicas de programação orientada a objetos.
Portanto, não é surpreendente que uma das maiores autoridades neste assunto seja Peter Coad, autor dos livros "Object Oriented Analysis" (1990) e "Object Oriented Design" (1991) entre outros. Para ele, "OOA é o desafio de entender o domínio do problema e depois as responsabilidades do sistema sob esta luz." ou, em outra palavras, "... análise é o estudo do domínio de um problema, levando à especificação de um comportamento externamente observável; uma completa, consistente e viável declaração do que é necessário; uma cobertura funcional e quantificada das características operacionas (por exemplo confiabilidade, disponibilidade, performance)" e OOD (...) " é a prática de tomar uma especificação de um comportamento externamente disponível e adicionar detalhes necessários para sua implementação em sistemas de computador, incluindo detalhes sobre interação humana, gerenciamento de tarefas e gerenciamento de dados".
Enfim, por que toda essa história é importante? A progressão usual de OOA para OOD paraOOP corresponde aproximadamente ao modelo de desenvolvimento conhecido comoWaterfall de Royce (1970), e as metodologias OO modernas praticamente buscam reduzir os problemas principais desse modelo, tais como os listados por Humphrey (1989):
  • Ele não responde adequadamente a mudanças.
  • Ele assume um sequência relativamente uniforme e ordenada das etapas de desenvolvimento.
  • Ele não prevê métodos como prototipagem rápida ou linguagens avançadas.
Essas e outras dificuldades levaram pessoas como Barry Boehm e Tom Gilb a criarem alternativas como o "Spiral Model" e o "Incremental Model" de sua autoria, na respectiva ordem. A aparição desses novos modelos certamente influenciou Coad (1991) a apresentar o seguinte resumo do ciclo de desenvolvimento:
Waterfall
  • Análise
  • Design
  • Programação
Spiral [Boehm, B. Spiral Model, 1988]
  • Análise, prototipagem, gerenciamento de risco
  • Design, prototipagem, gerenciamento de risco
  • Programação, prototipagem, gerenciamento de risco
Incremental [Gilb, T. Principles of Software Engineering Management, 1988]
  • Um pouco de Análise
  • Um pouco de Design
  • Um pouco de Programação
  • Repita
Esses modelos alternativos são a origem das metodologias de OO modernas, cujos enfoques variam de acordo com a vontade dos seus "criadores". Atualmente a moda é enfatizar o desenvolvimento incremental, iterativo, evolucionário, concorrente e a "natureza situacional do software". Um bom exemplo é o Manifesto Ágil".
Portanto, para desenvolver software é importante, além de conhecer as várias metodologias, ter uma compreensão profunda sobre OOA e OOD, uma vez que muitos dos problemas podem ser modelados através de OO. Mais que isso, para ser um bom gerente e teórico da ciência do desenvolvimento de software, o importante de facto é jamais esquecer que somos todos humanos e queremos viver bem em sociedade.
Todas as pessoas querem ter onde morar, o que comer, como se divertir e ainda manter isso ao longo da vida. Por isso, não colocar nenhum indivíduo em má posição perante seus superiores; permitir que ele participe da resolução do problema; saber que às vezes as necessidades mudam com o tempo e entregar sistemas que cumprem sua tarefa é o que importa no final das contas; porque, de forma geral, é o que aproxima as pessoas envolvidas no projeto e assegura que as vitórias ou derrotas sejam compartilhadas de forma coletiva.
Isso pode parecer bobagem e algo que todas as pessoas já sabem, mas o tema é tão crítico que é colocado como diferencial em novas metodologias. Quem não leu "Individuals and interactions over processes and tools" ou "Customer collaboration over contract negotiation"? Bastaria que as pessoas no mundo sentissem mais empatia para que não precisássemos "descobrir" algo que deveria ser natural para uma espécie dita social.

Linguagens Baseada em Objetos e Orientada a Objetos

Atualmente é bem aceito que: "object-oriented = data abstractions + object types + type inheritance" (OO). Tanto Cardelli (1985), Wegner (1985), como Booch (1991) chegaram a este consenso.
Mais tarde, Booch (1994) separou object types em encapsulation e modularity e chamou type inheritance de hierarchy. Imagino que Booch fez isso possivelmente para enfatizar que os objetos muitas vezes, para modelar melhor a realidade, possuem um estado interior ao qual o mundo externo não possui acesso (encapsulation).
Imagine a tarefa de modelar uma pessoa sem levar em consideração o "encapsulamento": a pessoa simplesmente seria incapaz de mentir sobre seu estado atual, todos saberiam se a pessoa está realmente feliz ou infeliz. Não haveria os mistérios do tipo "A vida dela era tão perfeita, por que será que ela se matou?". Parece-me, portanto, que é válido permitir que a modelagem de objetos em programação também selecione quais estados o mundo exterior terá acesso e também que este acesso seja filtrado antes da informação ser emitida. Quantas vezes já perguntamos para uma pessoa querida: "Tudo bem com você?" e ouvimos: "Tudo bem...", mesmo quando a situação era difícil...
Além desses requisitos, existem outras três características (pure) que geralmente são verificadas para classificar uma linguagem puramente orientada a objetos (mas se não é pura, ela não é, ok?):
  1. Todos os tipos pré-definidos são objetos.
  2. Todas as operações são realizadas através do envio de mensagens a objetos.
  3. Todos os tipos definidos pelo usuário são objetos.
Esse conjunto de requisitos, somado à hipótese de que uma linguagem só é orientada a objetos se todas essas características estão presentes na linguagem de forma explícita; isto é, sem ter que escrever uma plataforma ou utilizar convenções de codificação para suprir todos os requisitos; é o que nos permite diferenciar linguagens baseadas em objetos e orientadas a objetos.
Antes de começar a citar algumas linguagens famosas e o porquê de elas serem orientadas a objetos ou não, gostaria de enfatizar que OOP existe independentemente do fato de a linguagem ser orientada a objetos, pois para isso basta que a linguagem e a forma de se programar utilizem como base "data abstractions + object types + type inheritance".
Outro fato que acho interessante é o grande número de pessoas que discutem e brigam, tentando defender que a sua linguagem é orientada a objetos. Gente, ser uma linguagem orientada a objetos não é uma característica que faz a linguagem ser melhor do que as outrasNem a programação orientada a objetos, nem a linguagem ser orientada a objetos são garantias de qualidade. Muito pelo contrário, se apegar tanto a uma forma de pensar e escrever traz algumas vantagens para os iniciantes, mas existem também desvantagens que só aparecem sob a luz da experiência no desenvolvimento de muitos sistemas conceitualmente diferentes e experimentação de muitas linguagens.
Acho que uma analogia pertinente é a questão: "Linguagens (humanas) só de ideogramas, como o chinês, são melhores do que linguagens sem nenhum ideograma, como o português?" e a resposta, embora eu não saiba, é que vejo tanto chineses como portugueses se expressando muito bem, não importando qual conjunto de regras impostas pela linguagem.
Aliás, vivemos atualmente um forte retorno à iconografia. Basta você escrever :) nomessenger que automaticamente a pessoa com quem você está conversando sabe seu estado emocional (feliz), não é verdade? Não seria a utilização dos emoticons uma evidência de que os ideogramas tem seu espaço na comunicação? Ou a escrita japonesa que possui tanto Kanjis (ideogramas) quanto Hiraganas e Katakanas (esses dois últimos como se fossem sílabas) um exemplo da vantagem do "multi-paradigmatismo"?
Dito isso, acendam a fogueira para queimar o herege, vamos utilizar a plataforma de diferenciação de linguagens baseadas em objetos e orientadas a objetos definida acima.
Linguagens como SmalltalkRubyC#Scala e Fantom são orientadas a objetos, pois satisfazem aos seis critérios. Algumas linguagens como C++ e Javascript são multi-paradigma e possuem mecanismos nativos para implementar OO, mas não se preocupam em satisfazer todas as características.
C++, por exemplo, utiliza tipos nativos e Javascript que apenas não se preocupa comencapsulation de forma explícita por não precisar, pois o mesmo efeito é obtido através da utilização correta de closuresJava e Python geralmente esperneiam dizendo que são orientadas a objetos, mas elas não satisfazem as características (pure). Java, por exemplo, faz uso de tipos nativos e Python possui algumas operações interessantemente implementadas como globais.
Visual Basic, VBScript, PHP, Perl também não são por vários motivos, apesar de oferecerem um suporte básico para programadores buscando OOP. Outras linguagens como C, Lisp eErlang nem sequer se importam em ser ou parecer orientadas a objetos.
That's all folks. Espero que vocês tenham gostado do artigo e até a próxima, onde mostrarei algumas formas de como programar OOP em VBScript.

Links interessantes na web

Referências Bibliográficas

  1. Booch, G. Object-Oriented Analysis and Design, with Applications (2nd Ed.), 1994
  2. Booch, G. Object Oriented Design, 1991
  3. Coad, P. Object Oriented Design, 1991
  4. Coplien, James O. Advanced C++ Programming Styles and Idioms, 1992
  5. Cox, Brad J. Object Oriented Programming: An Evolutionary Approach, 1991
  6. Humphrey, W. Managing the Software Process, 1989
  7. Rumbaugh, J., Blaha, M., Premerlani, W., Eddy, F., & Lorensen, W. Object-Oriented Modeling and Design, 1991

Nenhum comentário:

Postar um comentário