Por que não há uma definição consistente de conceitos essenciais para OOP?

12

Eu sou muito novo em programação e um pouco confuso ao ler \ ouvir diferentes convenções de diferentes fontes:

A programação orientada a objetos tem 4 ou 5 conceitos?

Como recém-chegado, entendo que estes são os 5 conceitos:

  • Abstração
  • Herança
  • Encapsulamento
  • Polimorfismo
  • Modularidade

Então, por que não encontro uma definição mais "rigorosa" e parece haver vários arranjos desses conceitos por aí?

JohnDoea
fonte
7
Talvez porque isso não seja como matemática (alguns conceitos em CS são, mas acho que OOP não pertence a essa categoria), então não há definições estritas para começar. Então, por exemplo, qual a importância da 'modularidade'? É realmente tão especial para o OOP que precisamos mencioná-lo ou seria apenas algo que acontece por si só se aplicarmos os outros quatro corretamente? Algumas listas adicionam 'hierarquia', mas isso é realmente algo extra ou apenas segue de herança e polimorfismo?
224166 Thorsten Müller
6
Aviso: Como um programador muito novo, você não deve se incomodar tanto com a compreensão da terminologia e da teoria. Colete alguma experiência prática de programação primeiro, e ficará muito mais óbvio do que essas pessoas estão falando.
Philipp
9
Outra coisa é que OOP está mudando ao longo do tempo. Muito foco nos primeiros dias de C ++ (eu sei que o POO está mais distante do que isso) era sobre herança e polimorfismo. O foco de hoje é muito mais em Abstração e Encapsulamento.
Bent
3
Alguma discussão interessante sobre a falta de precisão na definição de OO pode ser encontrada aqui: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
MichelHenrich

Respostas:

27

A razão pela qual você encontra explicações diferentes sobre o que significa programação orientada a objetos é porque não há uma pessoa ou organização com autoridade para formular uma definição estritamente aplicável universalmente.

A programação orientada a objetos não é um padrão ISO ou uma lei científica. É uma filosofia. E, como em todas as filosofias, existem todos os tipos de interpretações diferentes e nenhuma interpretação é universalmente aplicável. Ao ler um texto que diz quais conceitos você deve seguir ao projetar uma arquitetura de software, você deve vê-lo como uma diretriz baseada nas opiniões que o autor formou durante sua experiência profissional e não como uma verdade universal.

Philipp
fonte
12

A programação orientada a objetos possui 5 ou 4 componentes?

Como outros já mencionaram, "OO" não possui realmente nenhum componente , porque é uma maneira de pensar em modelar soluções para problemas e não um kit de ferramentas nem um conjunto de processos claramente definidos.

Como recém-chegado, entendo que estes são os 5 componentes:

Abstração, herança, encapsulamento, polimorfismo e modularidade?

Herança e polimorfismo são recursos da linguagem de programação. É bom que você entenda isso, mas lembre-se de que são ferramentas (o que significa que, como em qualquer outra ferramenta, elas só devem ser usadas para solucionar problemas específicos e não devem ser tratadas como uma meta ou algo a ser buscado). Você pode (e geralmente deve) escrever o código "OO" sem usar nenhum deles. Alguns dos melhores códigos "OO" que eu já vi fazem muito pouco uso de herança ou polimorfismo.

Abstração, encapsulamento e modularidade têm menos a ver com código e mais com a maneira como você olha para um problema, como tenta entender esse problema e como projeta e estrutura sua solução em código.

Além disso, essas idéias de design não são exclusivas de "OO". As chances são de que você provavelmente as entenda agora em um nível básico, o que poderia incluir a capacidade de explicar uma definição perfeita para um livro didático e aplicá-las a problemas um tanto triviais; embora um teste mais profundo de compreensão esteja recebendo um problema complexo muito grande e com que complexidade você pode lidar.

Outro teste de entendimento é a abordagem usada para resolver um problema; e recém-chegados ao "OO", que são frequentemente ensinados sobre OO em termos de modelagem de dados (porque é assim que a maioria das pessoas costumava entendê-lo nos anos 90), e geralmente acabam focados nos aspectos errados de um problema - ou seja, eles se concentram muito em dados e eles não se concentram o suficiente no comportamento.

Por exemplo, exemplos clássicos muitas vezes se referem a entidades tais como Dog, Cat, Elephant, Seagull, Shark, etc. Os recém-chegados "OO", muitas vezes olhar para exemplos e imediatamente pensar "Oh, eu preciso de uma entidade base chamada Animal" , e eles podem até mesmo acabar com outra entidades intermediárias como Mammale Amphibianem uma hierarquia de herança pura, com atributos diferentes em cada uma.

Embora esse modo de pensar demonstre um entendimento muito básico de vários conceitos de OO, um programador experiente de OO nunca abordaria isso dessa maneira nem chegaria a essa conclusão (e na verdade reclamaria por não ter informações suficientes), porque essa abordagem demonstra Entidade modelagem em vez de modelagem OO, e porque o exemplo artificial não diz nada sobre o comportamento desses animais (e muitas pessoas argumentam hoje em dia que a essência do OO está toda no comportamento e na funcionalidade).

O caminho para aprender sobre "OO" tradicionalmente envolve gastar tempo construindo abstrações erradas quando você não sabe nada (ou muito pouco) sobre o comportamento do problema que está modelando ou quando comete o erro de concentrar sua atenção nas entidades, em vez de funcionalidade, embora parte disso seja porque muitos livros, cursos e tutoriais on-line escritos ao longo dos anos têm orientado (mis) os alunos por esse caminho há muito tempo (embora a maré esteja mudando).

No geral, grande parte do seu entendimento se resume à experiência. Esses conceitos que você aprendeu até agora são um bom começo, há mais conceitos que você precisará aprender ao longo do caminho (por exemplo, princípios "SÓLIDO" e "SECO") e precisará gastar muito tempo colocando teoria em prática com problemas reais de alta complexidade antes que tudo isso "se encaixe" no lugar.

Ben Cottrell
fonte
2
Um tubarão e um sapo nadam, mas um é um peixe, o outro é um anfíbio. Eu acho que esse exemplo descreve bem o seu ponto.
precisa
10

O termo "Orientação a Objetos" foi cunhado pelo Dr. Alan Kay, então ele é a fonte autorizada sobre o que significa e o define assim :

OOP para mim significa apenas mensagens, retenção e proteção local e ocultação de processos estatais e vinculação extrema de todas as coisas.

Vamos detalhar isso:

  • sistema de mensagens ("despacho de método virtual", se você não estiver familiarizado com o Smalltalk)
  • processo estadual deve ser
    • retido localmente
    • protegido
    • escondido
  • extrema ligação tardia de todas as coisas

Em termos de implementação, o sistema de mensagens é uma chamada de procedimento com limite tardio e, se as chamadas de procedimento são limitadas com atraso, não é possível saber em tempo de design o que você chamará, portanto, não é possível fazer suposições sobre a representação concreta do estado. Então, realmente se trata de mensagens, a ligação tardia é uma implementação de mensagens e o encapsulamento é uma conseqüência disso.

Mais tarde, ele esclareceu que " a grande idéia é ' enviar mensagens' " e lamenta tê-la chamado de "orientado a objetos" em vez de "orientado a mensagens", porque o termo "orientado a objetos" coloca o foco na coisa sem importância (objetos ) e distrai o que é realmente importante (mensagens):

Apenas um lembrete gentil de que eu me esforcei no último OOPSLA para tentar lembrar a todos que o Smalltalk não é apenas NÃO sua sintaxe ou a biblioteca de classes, nem mesmo sobre aulas. Sinto muito que, há muito tempo, cunhei o termo "objetos" para este tópico porque leva muitas pessoas a se concentrarem na idéia menor.

A grande idéia é "mensagens" - é disso que trata o kernal do Smalltalk / Squeak (e é algo que nunca foi completamente concluído em nossa fase do Xerox PARC). Os japoneses têm uma pequena palavra - ma - para "o que está no meio" - talvez o equivalente em inglês mais próximo seja "intersticial". A chave para criar sistemas grandes e cultiváveis ​​é muito mais para projetar como seus módulos se comunicam do que quais devem ser suas propriedades e comportamentos internos. Pense na Internet - para viver, ela (a) precisa permitir muitos tipos diferentes de idéias e realizações que estão além de qualquer padrão único e (b) permitir graus variados de interoperabilidade segura entre essas idéias.

(É claro que hoje em dia a maioria das pessoas nem se concentra nos objetos, mas nas classes, o que é ainda mais errado.)

As mensagens são fundamentais para o OO, tanto como metáfora quanto como mecanismo.

Se você envia uma mensagem a alguém, não sabe o que ela faz. A única coisa que você pode observar é a resposta deles. Você não sabe se eles mesmos processaram a mensagem (por exemplo, se o objeto possui um método), se encaminharam a mensagem para outra pessoa (delegação / proxy), se eles a entenderam. É disso que se trata o encapsulamento, do OO. Você não pode nem distinguir um proxy do real, desde que ele responda como você espera.

Um termo mais "moderno" para "sistema de mensagens" é "envio dinâmico de método" ou "chamada virtual de método", mas que perde a metáfora e se concentra no mecanismo.

Portanto, existem duas maneiras de analisar a definição de Alan Kay: se você a considerar por conta própria, poderá observar que as mensagens são basicamente uma chamada de procedimento de ligação tardia e a ligação tardia implica encapsulamento, para que possamos concluir que # 1 e # 2 são realmente redundantes, e OO é tudo sobre ligação tardia.

No entanto, mais tarde ele esclareceu que o importante é o envio de mensagens e, portanto, podemos vê-lo de um ângulo diferente: o envio de mensagens é tardio. Agora, se as mensagens fossem a única coisa possível, o nº 3 seria trivialmente verdadeiro: se houver apenas uma coisa, e essa coisa for atrasada, todas as coisas serão atrasadas. E mais uma vez, o encapsulamento segue as mensagens.

Pontos semelhantes também são apresentados em On Understanding Data Abstraction, revisitado por William R. Cook e também em sua Proposta de definições modernas e simplificadas de "Objeto" e "Orientado a objetos" .

O envio dinâmico de operações é a característica essencial dos objetos. Isso significa que a operação a ser invocada é uma propriedade dinâmica do próprio objeto. As operações não podem ser identificadas estaticamente e, em geral, não há como exatamente qual operação será executada em resposta a uma determinada solicitação, exceto executando-a. É exatamente o mesmo que nas funções de primeira classe, sempre despachadas dinamicamente.

No Smalltalk-72, não havia nenhum objeto! Havia apenas fluxos de mensagens que foram analisados, reescritos e redirecionados. Primeiro vieram os métodos (maneiras padrão de analisar e redirecionar os fluxos de mensagens), depois vieram os objetos (agrupamentos de métodos que compartilham algum estado privado). A herança veio muito mais tarde, e as classes foram introduzidas apenas como uma maneira de apoiar a herança. Se o grupo de pesquisa de Kay já soubesse sobre protótipos, eles provavelmente nunca teriam introduzido aulas em primeiro lugar.

Benjamin Pierce, em Tipos e linguagens de programação, argumenta que o recurso definidor da orientação a objetos é a recursão aberta .

Então: de acordo com Alan Kay, OO é tudo sobre mensagens. De acordo com William Cook, OO tem tudo a ver com o envio de método dinâmico (que é realmente a mesma coisa). De acordo com Benjamin Pierce, OO tem tudo a ver com recursão aberta, o que basicamente significa que as referências automáticas são resolvidas dinamicamente (ou pelo menos é uma maneira de pensar), ou, em outras palavras, mensagens.

Como você pode ver, a pessoa que cunhou o termo "OO" tem uma visão bastante metafísica dos objetos, Cook tem uma visão bastante pragmática e Pierce uma visão matemática muito rigorosa. Mas o importante é: o filósofo, o pragmatista e o teórico concordam! Mensagens é o único pilar da OO. Período.

Observe que não há menção de herança aqui! A herança não é essencial para o OO. Em geral, a maioria das linguagens OO tem algum modo de reutilização da implementação, mas isso não necessariamente tem que ser herança. Também poderia ser uma forma de delegação, por exemplo. De fato, o Tratado de Orlando discute a delegação como uma alternativa à herança e como diferentes formas de delegação e herança levam a diferentes pontos de design dentro do espaço de design das linguagens orientadas a objetos. (Observe que, mesmo em linguagens que suportam herança, como Java, as pessoas são ensinadas a evitá-la, novamente indicando que não é necessário para o OO).

Jörg W Mittag
fonte
1
@DavidArno Seu comentário não é construtivo. O próprio Alan Kay afirma que cunhou o termo "objeto" para esse conceito (embora, suponho, não o próprio conceito). Se você vai contradizer uma autoridade conhecida sobre o assunto, pelo menos escreva um comentário mais construtivo.
Andrés F.
1
@DavidArno Além disso, o voto negativo é seu? Então, alguém dedicou um tempo para escrever uma lista abrangente de diferentes pontos de vista, de especialistas conhecidos, sobre o que significa OOP, e você a rejeitou porque discorda de uma única frase? Oookay.
Andrés F.
2
@AndresF. Essa resposta pode ser resumida como "existem duas escolas, a de Alan Kay e de todos os outros. Porque o primeiro cunhou o termo, ele automaticamente está certo e todos que discordam dele estão errados". É um apelo à resposta falácia da autoridade. Assim, o voto negativo.
David Arno
2
Na verdade, essa resposta pode ser resumida como "existem três escolas de pensamento, vindas de três ângulos completamente diferentes e ninguém discorda de ninguém; de fato, elas estão todas de acordo". O prescritivista linguístico diria: Alan Kay inventou o termo, ele começa a dizer o que significa e diz que significa mensagem. O descritivista lingüístico diria que não, Alan Kay não diz nada, temos que ver como o termo é realmente usado , e foi o que Cook fez: ele estudou as linguagens que são comumente descritas como OO (Java, C ++ , C #, etc.) têm em comum, e que encontrou
Jörg W Mittag
3
Ele estudou o que os idiomas comumente descritos como não OO estão ausentes e os idiomas comumente descritos como OO, e ele descobriu uma coisa: as mensagens. O teórico da torre de marfim pega o cálculo λ e analisa qual o menor conjunto de recursos que seria necessário adicionar para obter algo que é comumente descrito como OO, e ele chega à recursão aberta , que é basicamente o alicerce para as mensagens .
Jörg W Mittag
3

Como afirma @Philipp, a raiz do problema é que não há uma definição oficial do que torna uma linguagem de programação orientada a objetos. Na verdade, isso é provavelmente uma coisa boa. Existem várias maneiras de oferecer suporte à programação OO, cada uma com suas próprias vantagens e desvantagens. Discussões sobre quais idiomas são mais "OO puros" não alcançam muito.

No entanto, olhando para os cinco atributos que você listou, na minha opinião a modularidade é definitivamente a mais estranha. A modularidade é realmente um atributo de um programa, não uma linguagem de programação. No nível lingüístico, o atributo é "suporte à modularização", e isso geralmente assume a forma de um mecanismo "modules" pr "packages".

Mas minha verdadeira objeção à Modularity é que ela não é essencial para a programação OO ou linguagens de programação OO, na medida em que a linguagem de programação arquetípica Smalltalk-80 não suportava módulos. E quando você pensa sobre isso, o suporte linguístico para módulos em muitos OOPLs amplamente usados ​​é "fraco".

Os módulos são projetados para oferecer suporte à "programação em grandes dimensões" ... onde sua base de código fica grande demais para uma única pessoa entender completamente. E você não precisa de módulos em uma linguagem de programação para modularizar seu código.


Não estou entrando no debate sobre os outros quatro atributos e se (por exemplo) quais modelos de "herança" são pura OO. Além disso, embora Alan Kay seja creditado por ter inventado a programação OO, isso não significa necessariamente que suas definições de OO / e OOPL tenham primazia. Claramente, este não é o caso. Ele é uma fonte autorizada, mas há outras fontes que dão outras definições para OO e OOPLs que (na prática) têm maior peso.

Stephen C
fonte
2
De fato, a modularidade +1 é amplamente aceita como um atributo desejável para a maioria dos sistemas de software, independentemente da linguagem de programação e do paradigma usado. Muitos idiomas que não são OO têm suporte para modularização.
Andrés F.
+1 @AndresF. Comente. De fato, "programação estruturada" e "refinamento passo a passo" (uma técnica para pensar na estrutura do código) saem do crisol de "aumentar a complexidade, resultando em software ainda pior". Se precedeu a COBOL, o idioma não teria uma reputação tão negativa no IMHO. E eu vejo OO pragmaticamente como uma estrutura simplesmente de ordem superior. E quero dizer que sem a estrutura subjacente OO não é melhor que o pior COBOL.
Radarbob 11/03/16