Saudações! Antes de mais nada, gostaria de me desculpar pelo longo
período entre o terceiro e quarto artigos desta série. Existe uma razão por trás da
demora, mas peço que simplesmente me desculpem para irmos logo ao que
interessa.
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.
A 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 OOP está 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, OOA, OOD
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:
- ASP, uma tecnologia mal interpretada.
- Programação orientada a eventos e lambda function em ASP/VBScript.
- TDD (Test Driven Development) em ASP/VBScript.
- Linguagens: Baseada em Objetos e Orientada a Objetos.
- Orientação a Objetos em VBScript “Hackers way”.
- Scripting Components, os “Às” na manga.
- 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 do UML:
“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 para OOP corresponde aproximadamente ao modelo de desenvolvimento conhecido como Waterfall 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?):
- Todos os tipos pré-definidos são objetos.
- Todas as operações são realizadas através do envio de mensagens a objetos.
- 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 a 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 outras. Nem
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
🙂 no messenger 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 Smalltalk, Ruby, C#, 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
com encapsulation de forma explícita por não precisar, pois o mesmo efeito é obtido através da utilização correta de closures. Java 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 e Erlang 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
- http://stason.org/TULARC/software/object-oriented-programming/
- http://www.jvoegele.com/software/langcomp.html
- http://en.wikipedia.org/wiki/Object-based
- http://en.wikipedia.org/wiki/Object-oriented_programming#OOP_languages
Referências Bibliográficas
- Booch, G. Object-Oriented Analysis and Design, with Applications (2nd Ed.), 1994
- Booch, G. Object Oriented Design, 1991
- Coad, P. Object Oriented Design, 1991
- Coplien, James O. Advanced C++ Programming Styles and Idioms, 1992
- Cox, Brad J. Object Oriented Programming: An Evolutionary Approach, 1991
- Humphrey, W. Managing the Software Process, 1989
- Rumbaugh, J., Blaha, M., Premerlani, W., Eddy, F., & Lorensen, W. Object-Oriented Modeling and Design, 1991