Orientação a objetos
Programação Orientada a Objeto ou Modelagem Orientada ao Objeto, é um modelo/paradigma de projeto e programação de software baseado na abstração digital do mundo real, através da composição e interação entre diversas unidades chamadas de 'objetos' e as classes ; baseado em quatro principais componentes da programação: abstração digital, encapsulamento, herança e, polimorfismo.
Imagem: TargetTrust · BY-NC · Openverse
Dentre as várias abordagens de orientação ao objeto, as baseadas no uso de classes são as mais comuns: esta representa um conjunto de objetos com características semelhantes; define o comportamento dos objetos através de métodos; define quais estados ele é capaz de manter através de seus atributos. Esta pode gerar subclasses que herda as todas as características. Um objeto é algo que pode ser manipulado, é criado a partir de uma classe através do processo de programação chamado instanciamento (instanciar um objeto). Onde os objetos são operados com o conceito de 'this' (isto) ou 'self' (si), de forma que seus métodos (muitas vezes) modifiquem os dados da própria instância, que também define o tipo do objeto. Cada classe determina o comportamento (definido nos métodos) e estados possíveis (atributos) de seus objetos, assim como o relacionamento com outros objetos. A alternativa mais usual ao uso de classes é o uso de protótipos. Neste caso, os objetos são cópias de outros objetos, e não são mais instâncias de classes; as linguagens Javascript e Lua são exemplos onde o POO é baseada em protótipos. A diferença prática mais evidente é neste tipo de POO/protótipos, apenas a herança simples é implementada pela cópia do objeto. Assim, implementa-se um conjunto de classes passíveis de serem instanciadas como objetos, por exemplo na linguagem Python e C++ - ou objetos protótipos que são copiados e alterados, por exemplo nas linguagens JavaScript e VimL).
Imagem: TargetTrust · BY-NC · Openverse
Muitas das linguagens de programação mais utilizadas atualmente (talvez a maioria) são multi-paradigma com suporte nativo à POO, como por exemplo: C++, C#, VB.NET, Java, Object Pascal, Objective-C, Python, SuperCollider, Ruby e Smalltalk. Já as linguagens ActionScript, ColdFusion, Javascript, PHP (a partir da versão 4.0), Perl (a partir da versão 5), Visual Basic (a partir da versão 4), VimL (ou Vim script) são exemplos de linguagens de programação com suporte a orientação a objetos. Vivace é um exemplo de linguagem sem suporte à POO.
Imagem: TargetTrust · BY-NC · Openverse
Além da programação estruturada, a POO incorpora as seguintes diretrizes:
Imagem: TargetTrust · BY-NC · Openverse
Tipo de Dados (TD ou simplesmente 'tipo') é um conjunto de valores que possuem propriedades em comum. Tipo abstrato de dados (TAD) é um Tipo de Dados em que o foco recai sobre a operações nos valores do tipo, em contraste com a representação destes valores. Estas operações escondem e protegem a representação dos dados enquanto facilitam o seu uso/manipulação. A POO é frequentemente compreendida e descrita como alicerçada nos TADs.
Legado de paradigmas anteriores
Linguagens pré-POO (em especial as que comportavam a programação estruturada) forneceram o seguinte legado à POO:
Novas características
Os atributos e métodos podem ser referentes a uma classe (e todas as suas instâncias) ou a uma única instância. O vínculo dos atributos aos métodos, de forma a manter uma interface bem definida para operação sobre os dados, e a evitar corrupção dos dados, é chamado de encapsulamento. O encapsulamento foi responsável pelo conceito de 'ocultamento de dados', central para a POO. O encapsulamento pode ser realizado através de convenções (em Python, underscores demarcam métodos e atributos protegidos e privados), ou via recursos da linguagem (em Java ou C++, um método privado só é acessado pela própria classe). Encapsulamento incentiva o desacoplamento.
Imagem: TargetTrust · BY-NC · Openverse
As críticas mais recorrentes à POO podem ser resumidas em:
Críticas de programadores notórios
Joe Armstrong: "O problema com linguagens orientadas a objetos é que você tem todo esse ambiente implícito que elas levam consigo. Você queria uma banana mas o que você conseguiu foi um gorila segurando a banana e uma selva inteira." Alexander Stepanov: "Dizer que tudo é um objeto é simplesmente dizer nada." Steve Yegge: "Por que alguém iria tão longe para colocar um só aspecto da fala [substantivos] em um pedestal?" Eric Steven Raymond: "A POO encoraja programas com muitas camadas e destrói a transparência." Rob Pike: "A POO constitui os números romanos da computação."
Imagem: TargetTrust · BY-NC · Openverse
Cliente, servidor e mensagens
Da passagem de mensagens entre objetos: o cliente (um objeto) emite uma mensagem para o servidor (outro objeto) em que solicita um serviço (i.e. que uma rotina qualquer seja executada) que pode implicar a emissão/retorno de uma resposta ao cliente. Um servidor pode ser cliente de outros (sub-)servidores. Esta resposta pode ser síncrona (quando o cliente aguarda a resposta do servidor para executar qualquer outra instrução) ou assíncrona (envolvendo paralelismo de atividades). Um exemplo simples: um instituto (cliente), solicita um buffet para uma empresa especializada (servidor). Esta empresa (agora cliente) solicita salgados e sucos de outras empresas (sub-servidores). O instituto pode ficar paralisado enquanto não chega o buffet (envio síncrono de mensagem) ou continuar suas atividades (envio assíncrono de mensagem). Neste último caso, o instituto deve ser capaz de lidar com a interrupção das atividades (ou parte delas) assim que chegar o buffet.
Responsabilidades
A um servidor e seus métodos são atribuídas responsabilidades específicas. No exemplo anterior, a empresa de buffet não deve entregar um brinquedo, e a comida deve ser apropriada (não apenas várias barras de chocolate, por exemplo). Uma responsabilidade que todos os servidores tem é a de manter seus dados consistentes. Idealmente, não deve ser possível tornar inconsistentes os dados de um objeto. Um objeto tem a responsabilidade de manter uma boa interface para se comunicar com outros objetos. Outra responsabilidade genérica e usual é a de que as operações tenham um sentido razoável. Por exemplo, se um cliente envia uma mensagem que satisfaz alguma pré-condição, é obrigação do método ativado retornar um resultado que reflita a pós-condição.
Modularidade centrada nos dados
A modularidade de um programa é uma medida que reflete o quanto ele é composto por partes separadas (chamadas de módulos). Na POO, a modularidade é preferencialmente (ou basicamente) centrada das TADs, o que pode ser chamado de modularidade centrada nos dados e possui as seguintes características:
Reuso
Enquanto na PE há bibliotecas de rotinas (procedure libraries), na POO há bibliotecas de classes, que podem (até certo ponto, em geral, etc) serem compreendidas com conjuntos de TADs reutilizáveis. Desafios para a reusabilidade: Nota: a modificação deve ser usada com cuidado. A modificação direta da rotina ou objeto implica dificuldades quando alguma versão nova da biblioteca é utilizada. Preferencialmente, as modificações devem ser feitas de forma modular, i.e. separando as contribuições locais das originais. Na POO, a herança ameniza este problema. Veja também o aberto/fechado.
Ação nos objetos
As ações devem sempre ser realizadas através de algum objeto.
Imagem: TargetTrust · BY-NC · Openverse
Metáforas são recorrentes em computação: mensagens, inteiros, etc. Classes e objetos são, em parte, inspirados na teoria de conceitos e fenômenos: Muitas classes representam conceitos da vida real pois muitos programas administram coisas do mundo real. No entanto, é comum que se faça uso também de conceitos imaginados (e.g. uma tabela hash). Ambos estes fatos favorecem a utilização da lógica fuzzy, mas na prática conceitos aristotélicos são convenientes para a construção de classes. O estabelecimento de conceitos a partir de conjuntos de fenômenos é chamado de classificação. A intenção sendo as propriedades definidoras que são compartilhadas dentre os fenômenos do conceito. A exemplificação é o oposto da classificação: um subconjunto da extensão do conceito. Agregar é formar um conceito que possui um número de partes (outros conceitos), i.e. é formar uma holonímia. Decompor é partir um conceito em um número de partes (outros conceitos), é formar meronímias. A intenção de um conceito agregado pode ser a intersecção das intenções de suas partes, pode ser a soma de suas intenções, ou pode possuir propriedades adicionais (em que o todo é mais que a soma das partes). Este último caso é útil na escrita de sistemas que envolvem sistemas complexos, e.g. para otimização bioinspiradas como por colonia de formigas, ou por enxame de partículas.
Imagem: TargetTrust · BY-NC · Openverse
A documentação pode ser escrita antes, durante ou depois da programação (e tipicamente, para um mesmo software, é escrita durante estes três momentos). A documentação pode ser distinta do programa, mas pode estar dentro do programa ou o programa dentro dela.
Imagem: TargetTrust · BY-NC · Openverse
Os seguintes verbetes foram contextualizados no restante deste artigo:


