OOP é difícil porque não é natural?


86

Pode-se ouvir com frequência que o POO corresponde naturalmente à maneira como as pessoas pensam sobre o mundo. Mas eu discordo totalmente dessa afirmação: nós (ou pelo menos eu) conceituamos o mundo em termos de relacionamentos entre as coisas que encontramos, mas o foco da OOP é projetar classes individuais e suas hierarquias.

Observe que, na vida cotidiana, existem relacionamentos e ações principalmente entre objetos que seriam instâncias de classes não relacionadas no POO. Exemplos de tais relacionamentos são: "minha tela está em cima da mesa"; "Eu (um ser humano) estou sentado em uma cadeira"; "um carro está na estrada"; "Estou digitando no teclado"; "a máquina de café ferve a água", "o texto é mostrado na janela do terminal."

Pensamos em termos de verbos bivalentes (às vezes trivalentes, como, por exemplo, "eu lhe dei flores"), onde o verbo é a ação (relação) que opera em dois objetos para produzir algum resultado / ação. O foco está na ação, e os dois (ou três) objetos [gramaticais] têm igual importância.

Compare isso com OOP, onde primeiro você precisa encontrar um objeto (substantivo) e dizer para ele executar alguma ação em outro objeto. O modo de pensar é deslocado de ações / verbos operando em substantivos para substantivos operando em substantivos - é como se tudo estivesse sendo dito em voz passiva ou reflexiva, por exemplo, "o texto está sendo mostrado pela janela do terminal". Ou talvez "o texto se desenhe na janela do terminal".

Não apenas o foco é deslocado para os substantivos, mas um dos substantivos (vamos chamá-lo de sujeito gramatical) recebe uma "importância" maior do que o outro (objeto gramatical). Portanto, é preciso decidir se alguém dirá terminalWindow.show (someText) ou someText.show (terminalWindow). Mas por que sobrecarregar as pessoas com decisões tão triviais, sem consequências operacionais, quando realmente significa mostrar (terminalWindow, someText)? [As consequências são operacionalmente insignificantes - em ambos os casos, o texto é mostrado na janela do terminal -, mas podem ser muito sérias no design das hierarquias de classes e uma escolha "errada" pode levar a um código complicado e difícil de manter.]

Eu diria, portanto, que a maneira principal de fazer OOP (despacho único e baseado em classe) é difícil, porque NÃO É NATURAL e não corresponde à maneira como os humanos pensam sobre o mundo. Os métodos genéricos do CLOS estão mais próximos do meu modo de pensar, mas, infelizmente, essa não é uma abordagem generalizada.

Diante desses problemas, como / por que aconteceu que a maneira atual de fazer POO se tornou tão popular? E o que, se alguma coisa, pode ser feito para destroná-lo?


OOP é para 'programação', é feito para que os compiladores gostem. não é uma maneira de modelar o mundo real de forma alguma. É comum usar exemplos do mundo real, como classe animal e classe retângulo, durante o ensino de POO, mas esses são apenas exemplos para simplificar os conceitos. Infelizmente, a linguagem de programação e os paradigmas 'acontecem' de maneira não evolutiva e não científica. Com poucas exceções, o processo de design da linguagem geralmente é filho do melhor palpite de poucas pessoas!
precisa saber é o seguinte

3
Eu discordaria da afirmação de que "o foco do OOP é projetar classes individuais e suas hierarquias". desde maio, é o foco de uma (s) certa (s) implementação (ões) de OOP, mas por exemplo descobri que linguagens dinâmicas de OOP geralmente não têm grandes hierarquias ou classes. Bem, a definição OOP pode mudar no futuro, há uma chance de mudar até mesmo o objeto wcook.blogspot.com/2012/07/proposal-for-simplified-modern.html
Azder

1
OOP está identificando objetos no sistema e construindo classes com base nesses objetos. Não o contrário. É por isso que também discordo de "o foco do OOP é projetar classes individuais e suas hierarquias".
Radu Murzea


1
Eu acho que essa é uma pergunta altamente subjetiva e está cheia de suposições estranhas sobre OOP e o que é o "mundo real" e como as pessoas pensam sobre problemas. E, finalmente, até pergunta: "E o que, se é que há alguma coisa, pode ser feito para destroná-lo?" o que realmente mostra que o OP tem uma opinião muito forte sobre isso. Se você é "religioso" sobre paradigmas de programação, acho que não precisa de respostas ... já sabe o que deseja ouvir. Se eu tivesse conhecido sobre esta questão quando foi perguntado em primeiro lugar, eu provavelmente votou para fechá-lo ...
Simon Lehmann

Respostas:


97

OOP não é natural para alguns problemas. Então, é processual. Então, é funcional. Eu acho que OOP tem dois problemas que realmente fazem parecer difícil.

  1. Algumas pessoas agem como se fosse a única maneira verdadeira de programar e todos os outros paradigmas estão errados. No IMHO, todos devem usar uma linguagem multiparadigmática e escolher o melhor paradigma para o subproblema no qual estão trabalhando atualmente. Algumas partes do seu código terão um estilo OO. Alguns serão funcionais. Alguns terão um estilo processual direto. Com a experiência, torna-se óbvio qual o melhor paradigma para o que:

    uma. OO geralmente é melhor para quando você tem comportamentos fortemente acoplados ao estado em que opera, e a natureza exata do estado é um detalhe de implementação, mas a existência dele não pode ser facilmente abstraída. Exemplo: Classes de coleções.

    b. Procedural é melhor para quando você tem vários comportamentos que não estão fortemente acoplados a nenhum dado específico. Por exemplo, talvez eles operem em tipos de dados primitivos. É mais fácil pensar no comportamento e nos dados como entidades separadas aqui. Exemplo: código numérico.

    c. Funcional é melhor quando você tem algo razoavelmente fácil de escrever declarativamente, de modo que a existência de qualquer estado seja um detalhe de implementação que possa ser facilmente abstraído. Exemplo: Mapear / Reduzir paralelismo.

  2. OOP geralmente mostra sua utilidade em grandes projetos onde é realmente necessário ter códigos bem encapsulados. Isso não acontece muito em projetos iniciantes.


4
Penso que um ponto importante na questão não era se a OOP é natural, mas se a abordagem convencional da OOP é a abordagem mais natural da OOP. (Boa resposta de qualquer maneira.)
Giorgio

11
"OOP geralmente mostra sua utilidade em grandes projetos onde é realmente necessário ter códigos bem encapsulados.": Mas isso não é uma propriedade específica do OOP, pois existem bons conceitos de módulo também para linguagens de programação imperativas, funcionais e ... .
Giorgio

2
OOP está realmente em um eixo diferente do processual / funcional; Ele aborda como organizar e encapsular o código, não como descrever as operações. (Você sempre . OOP parceria com um paradigma execução Sim, há OOP + linguagens funcionais.)
Donal Fellows

1
Não se pode dizer que OOP são apenas as caixas em que colocamos o material processual?
Erik Reppen

No OOP, você ainda pode escrever métodos. O que torna o POO mais fraco que a programação procedural?
Mert Akcakaya

48

IMHO é uma questão de gosto pessoal e modos de pensar. Eu não tenho muito problema com OO.

Nós (ou pelo menos eu) conceituamos o mundo em termos de relacionamentos entre as coisas que encontramos, mas o foco da OOP é projetar classes individuais e suas hierarquias.

IMHO isso não é bem assim, embora possa ser uma percepção comum. Alan Kay, o inventor do termo OO, sempre enfatizou as mensagens enviadas entre os objetos, e não os próprios objetos. E as mensagens, pelo menos para mim, denotam relacionamentos.

Observe que, na vida cotidiana, existem relacionamentos e ações principalmente entre objetos que seriam instâncias de classes não relacionadas no POO.

Se houver um relacionamento entre objetos, eles serão relacionados, por definição. No OO, você pode expressá-lo com uma dependência de associação / agregação / uso entre duas classes.

Pensamos em termos de verbos bivalentes (às vezes trivalentes, como, por exemplo, "eu lhe dei flores"), onde o verbo é a ação (relação) que opera em dois objetos para produzir algum resultado / ação. O foco está na ação, e os dois (ou três) objetos [gramaticais] têm igual importância.

Mas eles ainda têm seus papéis bem definidos no contexto: sujeito, objeto, ação etc. "Eu te dei flores" ou "Você me deu flores" não são a mesma coisa (sem mencionar "A flor te deu para mim": -)

Compare isso com OOP, onde primeiro você precisa encontrar um objeto (substantivo) e dizer para ele executar alguma ação em outro objeto. O modo de pensar é deslocado de ações / verbos operando em substantivos para substantivos operando em substantivos - é como se tudo estivesse sendo dito em voz passiva ou reflexiva, por exemplo, "o texto está sendo mostrado pela janela do terminal". Ou talvez "o texto se desenhe na janela do terminal".

Eu discordo disso. IMHO a frase em inglês "Bill, vá para o inferno" lê mais naturalmente no código do programa bill.moveTo(hell)do que no move(bill, hell). E o primeiro é de fato mais análogo à voz ativa original.

Portanto, é preciso decidir se alguém dirá terminalWindow.show (someText) ou someText.show (terminalWindow)

Novamente, não é o mesmo pedir ao terminal que mostre algum texto ou pedir que o texto mostre o terminal. IMHO, é bastante óbvio qual é o mais natural.

Diante desses problemas, como / por que aconteceu que a maneira atual de fazer POO se tornou tão popular?

Talvez porque a maioria dos desenvolvedores de OO vê OO de maneira diferente da sua?


15
1 para mencionar diretamente que as mensagens entre os objetos e sua importância de Alan Kay
bunglestink

3
@zvrba, de fato, havia outros pioneiros em OO também, mas isso não vem ao caso desta discussão. "O mais natural é pedir que o texto seja mostrado." - agora você está usando a mesma voz passiva que reivindicou é tão "antinatural" no POO.
Péter Török

5
@zvrba, você diz 'sempre há um "agente" [...] fazendo algumas coisas ", mas protesta contra a abordagem OO de identificar e nomear esses agentes (objetos), e tratá-los como cidadãos de primeira classe no idioma . Para mim, isso faz parte da modelagem do domínio do problema - você precisa fazer esse trabalho de qualquer maneira; basta mapear o modelo de domínio resultante para codificar de uma maneira diferente, dependendo se seu idioma é OO ou não.
Péter Török

6
@zvrba, não é OO em si, mas um desenvolvedor / designer que decide sobre as funções e responsabilidades de diferentes objetos. O uso da abordagem OO pode produzir modelos e projetos de domínio bons ou ruins, assim como o uso de uma faca pode lhe dar uma fatia de pão fino ou um dedo sangrando - ainda não culpamos a faca, porque é apenas uma ferramenta. Observe também que os conceitos / objetos / agentes no modelo são abstrações das coisas no mundo real e, como tal, sempre são limitadas e distorcidas, concentrando-se apenas em aspectos "interessantes" específicos.
Péter Török 20/03

6
@zvrba, um carro de fato não inicia por vontade própria - assim como um Carobjeto faria start()apenas quando seu método é explicitamente chamado por alguém.
Péter Török 20/03

10

Alguns programadores acham o OOD difícil, porque gostam de pensar em como resolver o problema no computador, e não em como o problema deve ser resolvido.

... mas o foco do OOP é projetar classes individuais e suas hierarquias.

OOD NÃO é sobre isso. OOD é descobrir como as coisas se comportam e interagem.

Pensamos em termos de verbos bivalentes (às vezes trivalentes, como, por exemplo, "eu lhe dei flores"), onde o verbo é a ação (relação) que opera em dois objetos para produzir algum resultado / ação. O foco está na ação, e os dois (ou três) objetos [gramaticais] têm igual importância.

O foco no OOD está sempre na ação, onde ações são os comportamentos dos objetos. Objetos não são nada sem seus comportamentos. A única restrição de objeto do OOD é que tudo precisa ser feito por alguma coisa.

Não vejo o executor como mais importante do que o que está sendo feito.

Mas por que sobrecarregar as pessoas com decisões tão triviais, sem consequências operacionais, quando realmente significa mostrar (terminalWindow, someText)?

Para mim, é a mesma coisa com uma notação diferente. Você ainda precisa decidir quem é o show-show e quem é o show-ee. Depois que você souber disso, não haverá decisão no OOD. O Windows mostra texto -> Window.Show (texto).

Um monte de coisas por aí (especialmente na área de legado) diz que é OO quando não é. Por exemplo, há uma enorme quantidade de código C ++ que não implementa uma figura do OOD.

OOD é fácil quando você deixa de pensar que está resolvendo um problema para computadores. Você está resolvendo problemas para coisas que fazem coisas.


10
Não gosto exatamente de OOD porque prefiro pensar em como resolver o problema, ponto final. Não quero pensar em como traduzir a linguagem natural de um domínio problemático em um mundo alienígena de objetos, mensagens, herança e assim por diante. Não quero inventar taxonomias hierárquicas onde elas não existem naturalmente. Quero descrever o problema em sua linguagem natural e resolvê-lo da maneira mais fácil possível. E, a propósito, o mundo não é feito apenas de "coisas que fazem coisas". Sua visão sobre a realidade é extremamente estreita.
SK-logic

7
@ Matt Ellen, escrevo programas que modelam o comportamento de entidades que não são "coisas" e que não "fazem" nada ". Qualquer entidade imutável não faz nada. Qualquer função matemática pura não faz nada - é apenas um mapeamento de um conjunto para outro, e esse mundo é descrito principalmente por essas funções. Qualquer formalismo lógico não "faz" nada. Sim, o OOD não vai me ajudar, porque eu posso usar abstrações e modelos muito mais poderosos. Voltar a um OOD primitivo, limitado e limitador me prejudicará severamente.
SK-logic

2
@ Matt Ellen, sim, eu gostaria de ver referências que apóiam afirmações tão estranhas que o mundo é melhor visto como uma coleção de "coisas que fazem coisas" ou "objetos que interagem por meio de mensagens". É completamente antinatural. Pegue qualquer teoria científica (como todas elas estão tão próximas de modelar o mundo real quanto possível neste estágio) e tente reescrevê-la usando sua terminologia. O resultado será desajeitado e desajeitado.
SK-logic

4
@ Antonio2011a, não existe um único paradigma de programação ou modelagem que possa cobrir todos os domínios de problemas possíveis com eficiência. OOP, funcional, fluxo de dados, lógica de primeira ordem, tudo o mais - todos eles são paradigmas específicos de domínios problemáticos e nada mais. Só estou defendendo a diversidade e a abordagem de mente aberta para a solução de problemas. Reduzir seu pensamento a um único paradigma é simplesmente estúpido. A coisa mais próxima de uma abordagem universal, não se limitando a uma única estrutura semântica, é en.wikipedia.org/wiki/Language-oriented_programming
SK-lógica

3
@Calmarius, por que você facilitaria a programação para computadores? Isso é bobagem. São os humanos que precisam fazer o trabalho mais duro.
Matt Ellen

7

Talvez eu não consiga entender, mas:

Ao ler o primeiro livro sobre OOP (início dos anos 90, o fino manual de Borland para Pascal) fiquei simplesmente surpreso com sua simplicidade e potencial. (Antes, eu usava Cobol, Fortran, linguagem Assembly e outras coisas pré-históricas.)

Para mim, é bem claro: um cachorro é um animal, um animal deve comer, meu cachorro é um cachorro, então deve comer ...

Por outro lado, a programação em si é inerentemente não natural (isto é, artificial). A fala humana é artificial (não me culpe, todos nós aprendemos nossos idiomas com outras pessoas, ninguém conhece a pessoa que inventou o inglês) também. Segundo alguns cientistas, a mente do ser humano é formada pela linguagem que ele aprendeu primeiro.

Admito que algumas construções nas linguagens OO modernas são um pouco estranhas, mas é a evolução.


1
Qual era exatamente o seu trabalho para você passar de cobol para fortran e depois para montagem (e o resto)?
Rook

1
Ordem errada. Na verdade, eu comecei com o Basic, depois mudei para Fortran e depois para Assembly e Cobol (sim, é a ordem correta: primeiro assembly). O primeiro computador da minha vida foi um mainframe "gigantesco", com 256kB de memória, máquina de escrever em seu console, alimentando-o com cartões perfurados, porque eu era seu operador. Quando me levantei o suficiente para me tornar um programador de sistemas, uma coisa suspeita chamada PC-AT aterrissou em minha mesa. Então eu mergulhei no GW-Basic, Turbo-Pascal, ... e assim por diante.
Nerevar

1
Eu não estava me referindo a isso. Mais para o seu domínio de trabalho; porque eu não conheço muitas pessoas (alguém realmente) que lidaram com COBOL (orientado a negócios), fortran (domínio científico), assembler (mais orientado a cs) e depois as outras. No entanto, eles são programadores profissionais ou não.
Rook

1
Não há mistério: unir equipes e projetos em que a decisão sobre a abordagem de linguagem já havia sido tomada antes. E um nível não trivial de curiosidade sobre as ferramentas que eles estavam usando.
Nerevar 21/03

6

Uma coisa que tornou difícil para mim foi pensar que OOP era sobre modelar o mundo. Eu pensei que se eu não entendesse direito, algo poderia vir e me morder na bunda (uma coisa é verdadeira ou não). Eu estava muito ciente dos problemas de fingir que tudo é um objeto ou entidade. Isso me deixou muito hesitante e pouco confiante em relação à programação em OOP.

Então li o SICP e cheguei a um novo entendimento de que realmente era sobre tipos de dados e como controlar o acesso a eles. Todos os problemas que eu derreteram porque foram baseados em uma premissa falsa de que no OOP você está modelando o mundo.

Ainda me surpreendo com a imensa dificuldade que essa falsa premissa me deu (e como me deixei contemplar).


Obrigado por apontar o perigo de tentar modelar o mundo.
Sean McMillan

4

Sim, o OOP em si é muito antinatural - o mundo real não é inteiramente feito de taxonomias hierárquicas. Algumas pequenas partes são feitas com essas coisas, e essas são as únicas coisas que podem ser adequadamente expressas em termos de OO. Todo o resto não pode se encaixar naturalmente em uma maneira tão trivial e limitada de pensar. Veja as ciências naturais, veja quantas linguagens matemáticas diferentes foram inventadas para expressar da maneira mais simples ou pelo menos compreensível a complexidade do mundo real. E quase nenhum deles pode ser facilmente traduzido para uma linguagem de objetos e mensagens.


5
Bem, isso é igualmente verdade para qualquer tipo de notação formal que tente descrever com precisão o mundo real.
Péter Török

1
@ Péter Török, precisamente o meu ponto. Não existe um formalismo único que cubra tudo. Você tem que usá-los todos, em toda a sua multidão assustadora. E é por essa razão que acredito em uma programação orientada a linguagem - ela permite adotar vários formalismos, muitas vezes incompatíveis, em uma entidade de código sólido.
SK-logic

1
Tudo pode ser categorizado em taxonomias hierárquicas. O truque é criar esquemas que façam sentido. A herança múltipla geralmente está envolvida. Uma grande diferença entre software e o mundo real é que, no mundo real, muitas vezes precisamos inferir ou descobrir os esquemas de categorização; em software, nós os inventamos.
Caleb

1
Usando um termo como "taxonomia hierárquica", acho que você está pensando em, bem, herança. Herança é de fato difícil de raciocinar. É por isso que as pessoas sugerem o uso da composição sobre a herança.
precisa saber é o seguinte

1
@Frank: Existem muitos tipos de taxonomias hierárquicas no mundo real, das quais a herança é apenas uma. Fazer isso requer todos devidamente ferramentas melhores do que OOP (por exemplo, raciocínio ontológica) e tem causado problemas para os filósofos para milênios ...
Donal Fellows

4

Nós (ou pelo menos eu) conceituamos o mundo em termos de relacionamentos entre as coisas que encontramos, mas o foco da OOP é projetar classes individuais e suas hierarquias.

Você está começando de (IMO) uma premissa falsa. Os relacionamentos entre objetos são sem dúvida mais importantes que os próprios objetos. São os relacionamentos que dão uma estrutura de programa orientada a objetos. Herança, o relacionamento entre classes, é obviamente importante porque a classe de um objeto determina o que esse objeto pode fazer. Mas são os relacionamentos entre objetos individuais que determinam o que um objeto realmente faz dentro dos limites definidos pela classe e, portanto, como o programa se comporta.

O paradigma orientado a objetos pode ser difícil a princípio não porque é difícil pensar em novas categorias de objetos, mas porque é difícil visualizar um gráfico de objetos e entender quais devem ser as relações entre eles, principalmente quando você não tem um maneira de descrever esses relacionamentos. É por isso que os padrões de design são tão úteis. Os padrões de design são quase inteiramente sobre os relacionamentos entre objetos. Os padrões nos fornecem os blocos de construção que podemos usar para projetar relacionamentos de objetos em um nível superior e uma linguagem que podemos usar para descrever esses relacionamentos.

O mesmo acontece em campos criativos que funcionam no mundo físico. Qualquer um poderia juntar um monte de quartos e chamá-lo de prédio. Os quartos podem até ser totalmente mobiliados com todos os acessórios mais recentes, mas isso não faz o prédio funcionar. O trabalho de um arquiteto é otimizar os relacionamentos entre essas salas com relação aos requisitos das pessoas que as utilizam e ao ambiente do edifício. Consertar esses relacionamentos é o que faz um edifício funcionar, tanto do ponto de vista funcional quanto estético.

Se você está tendo problemas para se acostumar OOP, eu encorajá-lo a pensar mais sobre como os objetos se encaixam e como as suas responsabilidades são organizados. Se você ainda não leu, leia sobre padrões de design - provavelmente perceberá que já viu os padrões sobre os quais leu, mas dar nomes a eles permitirá que você veja não apenas árvores, mas também suportes, copas, matagais, bosques, bosques, lotes e, eventualmente, florestas.


3

Isso é apenas uma parte do que há de errado com o OOP.

Essencialmente, as funções se tornam cidadãos de segunda classe, e isso é ruim.

Linguagens modernas (ruby / python) não sofrem esse problema e fornecem funções como objetos de primeira classe, além de permitir que você crie programas sem criar nenhuma hierarquia de classes.


OOP parece muito natural para mim, é realmente difícil pensar em programar tarefas de qualquer outra maneira. Ainda assim, ao longo dos anos, entendi que OOP tende a enfatizar excessivamente os substantivos em relação aos verbos. Esse discurso retórico de 2006 me ajudou a entender essa distinção: steve-yegge.blogspot.com/2006/03/…
Jim In Texas

3

OOP não é difícil. O que dificulta o bom uso é uma compreensão superficial do que é bom, onde os programadores ouvem máximas aleatórias e as repetem para si mesmos, a fim de receber as bênçãos da divina Gangue dos Quatro, o abençoado Martin Fowler, ou quem mais eles estiveram lendo.


3

EDITADO

Antes de mais, gostaria de dizer que nunca achei o POO difícil ou difícil do que outros paradigmas de programação. A programação é inerentemente difícil porque tenta resolver problemas do mundo real e o mundo real é extremamente complexo. Por outro lado, quando li essa pergunta, perguntei-me: OOP é "mais natural" do que outros paradigmas? E, portanto, mais eficaz?

Certa vez, encontrei um artigo (gostaria de poder encontrá-lo novamente para publicá-lo como referência) sobre um estudo comparativo entre programação imperativa (IP) e programação orientada a objetos (OOP). Eles basicamente mediram a produtividade de programadores profissionais usando IP e OOP em diferentes projetos, e o resultado foi que eles não haviam visto grandes diferenças. Portanto, a alegação era de que não havia grande diferença de produtividade entre os dois grupos e que o que conta realmente é a experiência.

Por outro lado, os defensores da orientação a objetos afirmam que, embora durante o desenvolvimento inicial de um sistema OOP possa levar mais tempo do que o necessário, a longo prazo, o código é mais fácil de manter e estender devido à forte integração entre dados e operações.

Eu trabalhei principalmente com linguagens OOP (C ++, Java), mas geralmente sinto que poderia ser tão produtivo usando Pascal ou Ada, mesmo que nunca as tenha experimentado em grandes projetos.

Compare isso com OOP, onde primeiro você precisa encontrar um objeto (substantivo) e dizer para ele executar alguma ação em outro objeto.

[cortar]

Eu diria, portanto, que a maneira principal de fazer OOP (despacho único e baseado em classe) é difícil, porque NÃO É NATURAL e não corresponde à maneira como os humanos pensam sobre o mundo. Os métodos genéricos do CLOS estão mais próximos do meu modo de pensar, mas, infelizmente, essa não é uma abordagem generalizada.

Quando li este último parágrafo com mais atenção, finalmente entendi o ponto principal da sua pergunta e tive que reescrever minha resposta do zero. :-)

Conheço outras propostas OO em que vários objetos recebem uma mensagem em vez de apenas uma, ou seja, vários objetos desempenham um papel simétrico ao receber uma mensagem. SIM, isso parece uma abordagem OOP mais geral e talvez mais natural (menos restritiva) para mim.

Por outro lado, o "despacho múltiplo" pode ser facilmente simulado usando o "despacho único" e o "despacho único" é mais fácil de implementar. Talvez essa seja uma das razões pelas quais o "envio múltiplo" não se tornou popular.


3

Pare de procurar um paradigma exclusivo de OOP e tente um pouco de JavaScript.

Atualmente, tenho um esquema elaborado em que meus objetos de interface do usuário estão operando em uma interface orientada a eventos. Ou seja, terei o que parece ser um método público típico que, quando disparado, resulta em uma ação definida internamente. Mas quando é acionado, o que realmente acontece é que eu aciono um evento no próprio objeto e um manipulador predefinido dentro desse objeto responde. Este evento e o objeto de evento ao qual você pode anexar propriedades que são passados ​​para qualquer outro ouvinte podem ser ouvidos por qualquer coisa que queira escutar. Você pode ouvir diretamente o objeto ou geralmente esse tipo de evento (os eventos também são acionados em um objeto genérico que todos os objetos construídos pela fábrica podem ouvir). Agora, por exemplo, eu tenho uma caixa de combinação onde você seleciona um novo item na lista suspensa.

Se você quiser (e fiquei surpreso ao descobrir que normalmente não quero - é um problema de legibilidade quando você não consegue ver de onde o evento vem), você pode ter uma dissociação completa de objetos e estabelecer o contexto por meio de um objeto de evento passado. Independentemente disso, você ainda está evitando o envio único ao registrar vários respondedores.

Mas não estou fazendo isso apenas com OOP e o JS nem sequer é 'adequadamente' por algumas definições, o que acho hilário. Adequado, para os níveis mais altos de desenvolvimento de aplicativos, na minha opinião, está o poder de dobrar o paradigma para o que funcione para a sua situação e podemos emular classes muito bem, se quisermos. Mas neste caso, estou misturando aspectos funcionais (passando manipuladores) com OOP.

Mais importante, o que tenho parece bastante poderoso. Não estou pensando em termos de um objeto agindo em outro. Basicamente, estou decidindo com o que os objetos se importam, dando a eles as ferramentas necessárias para resolver as coisas e simplesmente colocando-os em um misturador e deixando-os reagir um ao outro.

Então, acho que o que estou dizendo é o seguinte: não é um tipo de problema de declaração de switch. É misturar e combinar. O problema são as linguagens e os modismos que querem que você acredite que é uma coisa demais. Como um desenvolvedor java júnior, por exemplo, pode realmente apreciar o OOP quando pensa que está sempre fazendo isso corretamente por padrão?


2

O jeito que me foi explicado foi com uma torradeira e um carro. Ambos têm molas, então você teria um objeto de "mola" e eles teriam tamanhos, forças e o que quer que fosse, mas ambos seriam "molas" e estenderiam essa metáfora para o carro, se você tivesse muitas rodas (Rodas, obviamente, mais o volante, etc.) e isso fazia muito sentido.

Você pode pensar no programa como uma lista de objetos e é muito mais simples visualizar: "É uma lista de coisas que fazem coisas, por isso não é como a lista de instruções que você viu antes"

Eu acho que o verdadeiro problema com OOP é como é explicado às pessoas. Freqüentemente (nas minhas aulas da uni) eu vejo isso sendo explicado dizendo "trata-se de muitas classes que fazem pequenas coisas, e você pode criar objetos com isso" e tudo confunde muitas pessoas, porque está usando o que é essencialmente abstrato termos para explicar esses conceitos, e não idéias concretas que as pessoas entenderam quando tinham 5 anos de idade brincando com lego.


2
Molas vêm em milhões de formas, todas as quais desempenham funções semelhantes . Eu diria que este é um exemplo perfeito para programação funcional.
L0b0 18/03/11

2

É a maneira natural de pensar no mundo através da categorização. É mais ou menos do que trata o OO. OOP é difícil porque a programação é difícil.


Mas você classifica de acordo com alguns objetos terem atributos ou comportamentos comuns? Tudo o que tem nome e sobrenome é uma pessoa? Tudo o que anda é um animal?
Zvrba

Quando se trata de categorização, ser capaz de executar um determinado comportamento é um atributo. Zebras e cavalos podem se reproduzir, mas a prole é um híbrido. Muito difícil prever esse resultado com base na função de acasalamento, a menos que você saiba que não são da mesma espécie.
19411 JeffO

1
@zvrba: Minha resposta para a pergunta colocada no comentário é essa it doesn't matter. Tudo o que tem nome e sobrenome é uma pessoa de todos os programas que se preocupam apenas com as pessoas. Para qualquer programa que não tem conhecimento de pessoas ou não pessoas, é um IHasNameAndSurname. Os objetos precisam apenas resolver o problema em questão.
Tom W

@ Jeff O Mesmo dentro da mesma espécie / raça / população, há variação e nenhum exemplo ideal (essencial). Então, sim, o OO não é como a natureza realmente é, mas é um bom ajuste para como os seres humanos pensam naturalmente.
Tom Hawtin - defina

2

Eu acho que algumas das dificuldades surgem quando as pessoas tentam usar o POO para representar a realidade. Todo mundo sabe que um carro tem quatro rodas e um motor. Todo mundo sabe que carros podem Start(), Move()e SoundHorn().

Uma luz estalou na minha cabeça quando percebi que deveria parar de tentar fazer isso o tempo todo. Um objeto não é aquele com o qual ele compartilha um nome. Um objeto é (isto é, deveria ser) uma partição de dados suficientemente detalhada, relevante para o escopo do problema. É oughtter exatamente o que a solução para o problema precisa de ter, nem mais nem menos. Se responsabilizar um objeto por algum comportamento resulta em mais linhas de código do que o mesmo comportamento de terceiros nebulosos (alguns podem chamá-lo de 'poltergeist'), então o poltergeist ganha suas fichas.


1

Para gerenciar a complexidade, precisamos agrupar a funcionalidade em módulos, e esse é um problema difícil em geral. É como o velho ditado sobre capitalismo: OOP é o pior sistema para organizar software existente, exceto por tudo o que tentamos.

A razão pela qual agrupamos interações dentro dos substantivos, mesmo havendo frequentemente uma ambiguidade sobre qual dos dois substantivos o agrupar, é que a quantidade de substantivos funciona em classes de tamanho gerenciáveis, enquanto o agrupamento por verbos tende a produzir grupos muito pequenos como pontuais ou grupos muito grandes para uma função como show . Reutilizar conceitos como herança também funciona muito mais facilmente ao agrupar por substantivos.

Além disso, a questão de decidir se mostra ou não a janela ou o texto é quase sempre muito mais clara na prática do que na teoria. Por exemplo, quase todos os grupos de kits de ferramentas da GUI são adicionados ao contêiner, mas são mostrados com o widget. Se você tentar escrever o código de outra maneira, o motivo se tornará aparente rapidamente, mesmo que pensando abstratamente os dois métodos pareçam intercambiáveis.


2
Você já viu um sistema de módulos adequado ? Como você pode dizer que OOP é a melhor coisa disponível? Os módulos SML são muito, muito mais poderosos. Mas, mesmo os pacotes Ada são suficientes para a maioria dos casos, mesmo sem uma pequena dica de OOP.
SK-logic

@ SK-logic, acho que você está ficando preso a definições muito precisas. Por POO, não quero dizer classes , quero dizer agrupar logicamente "verbos" pelos "substantivos" em que operam e ser capaz de reutilizar e especializar esses verbos com base nos substantivos específicos em que eles operam. As classes são a implementação mais conhecida disso, mas não são a única implementação. Eu admito que não conheço os módulos SML, mas o primeiro exemplo que vi ao procurar foi a implementação de uma fila que poderia ter vindo de qualquer livro de design de OO com alterações de sintaxe para torná-lo funcional.
Karl Bielefeldt

simplesmente não seria justo dar muito crédito a uma OOP por algo que não lhe pertence. Módulos são uma ótima invenção. Os módulos de primeira classe são fantásticos. Mas OOP não tem nada a ver com eles. Algumas linguagens OOP adotaram alguns dos recursos do módulo (principalmente - namespaces), mas os módulos são muito mais genéricos e poderosos do que as classes. Você disse que as aulas são "as melhores", o que está longe de ser verdade. Módulos de primeira classe são muito melhores. E, é claro, os sistemas de tipos são muito mais amplos e mais profundos do que apenas um OO com seu subtipo de coisa.
SK-logic

1
"É como o velho ditado sobre capitalismo: OOP é o pior sistema para organizar software existente, exceto por tudo o que tentamos.": Talvez não tenhamos tentado o suficiente. :-)
Giorgio

1
Eu acho que você quer dizer 'democracia': quotationspage.com/quote/364.html
nicodemus13

1

Não . Existem várias maneiras de resolver um problema usando a Programação: funcional, Procedural, lógica, OOP, outra.

No mundo real, às vezes, as pessoas usam o paradigma funcional e, às vezes, usamos o paradigma processual, e assim por diante. E às vezes nos misturamos. E, eventualmente, nós os representamos como um estilo ou paradigma particular de programação.

Há também o paradigma "tudo é uma lista ou um item", usado no LISP. Eu gosto de mencionar como algo diferente da programação funcional . O PHP usa isso em matrizes associativas.

Os paradigmas de POO e "Tudo é uma lista ou item" são considerados dois dos estilos de programação MAIS NATURAIS , como me lembro em algumas aulas de Inteligência Artificial.

Parece-me estranho: "OOP não é natural", talvez o modo como você aprenda ou o modo como você aprendeu sobre OOP esteja errado, mas não o próprio OOP.


1

Diante desses problemas, como / por que aconteceu que a maneira atual de fazer POO se tornou tão popular? E o que, se alguma coisa, pode ser feito para destroná-lo?

OOP tornou-se popular porque oferece ferramentas para organizar seu programa em um nível mais alto de abstração do que as linguagens processuais populares que o precederam. Também era relativamente fácil criar uma linguagem que tivesse estrutura processual dentro dos métodos e estrutura orientada a objetos ao seu redor. Isso permite que os programadores que já sabiam programar proceduralmente escolham os princípios de OO, um de cada vez. Isso também levou a muitos programas OO-em-nome-somente que eram programas procedurais agrupados em uma ou duas classes.

Para destronar o OO, crie uma linguagem que facilite a transição incremental do que a maioria dos programadores conhece atualmente (principalmente processual, com um pouco de OO) para o seu paradigma preferido. Verifique se ele fornece APIs convenientes para executar tarefas comuns e promovê-lo bem. Em breve, as pessoas farão programas apenas com o nome X no seu idioma. Então você pode esperar anos e anos para que as pessoas se tornem boas em fazer o X.


O OP não argumenta que o OO é ruim em geral e deve ser destronado, mas que a "maneira atual de fazer POO" não é a mais natural (em comparação com o "despacho múltiplo").
Giorgio

O OP também parece excessivamente focado na definição da hierarquia de tipos, onde os melhores programas de OO tendem a depender mais de interfaces e composição. Se o despacho múltiplo for X, criar uma linguagem que permita às pessoas aprender gradualmente as habilidades associadas ao despacho múltiplo ainda é a chave para mudar o ambiente.
Sean McMillan

1

Eu acho que as linguagens OOP e OOP também têm problemas.

Se entendido corretamente, OOP refere-se a caixas pretas (objetos) que possuem botões que podem ser pressionados (métodos). As aulas estão lá apenas para ajudar a organizar essas caixas pretas.

Um problema é quando o programador coloca os botões no objeto errado. O terminal não pode mostrar texto em si mesmo, o texto não pode aparecer no terminal. O componente do gerenciador de janelas do sistema operacional que pode fazer isso. A janela e o texto do terminal são apenas uma entidade passiva. Mas se pensarmos dessa maneira, perceberemos que a maioria das entidades são coisas passivas e teríamos apenas muito poucos objetos que realmente fazem alguma coisa (ou simplesmente um: o computador ). De fato, quando você usa C, organiza-o em módulos, esses módulos representam poucos objetos.

Outro ponto é que o computador apenas executa as instruções sequencialmente. Vamos supor que você tenha VCRum Televisionobjeto e, como você reproduz um vídeo? Você provavelmente escreve algo como isto:

connect(television, vcr);
vcr.turnOn();
television.turnOn();
insert(vcr, yourFavoriteCasette);
vcr.play();
while (vcr.isPlaying()) {} // Wait while the VCR is playing the casette.
vcr.eject();
vcr.turnOff();
television.turnOff();

Isso seria simples, mas você precisaria de pelo menos três processadores ( ou processos ) para isso: um desempenha o seu papel, o segundo é o videocassete e o terceiro é a TV. Mas normalmente você tem apenas um núcleo (pelo menos não o suficiente para todos os seus objetos). Na faculdade, muitos dos meus colegas de classe não entendiam por que a GUI congela quando um botão faz uma operação cara.

Então, acho que um design orientado a objetos pode descrever o mundo muito bem, mas não é a melhor abstração para o computador.


0

Dê uma olhada no DCI (dados, contexto e interação) inventado pelo inventor do padrão MVC.

O objetivo do DCI é (citado na Wikipedia):

  • ao comportamento do sistema status de primeira classe, acima dos objetos (substantivos).
  • Separar claramente o código para alterar rapidamente o comportamento do sistema (o que o sistema faz) do código para alterar lentamente o conhecimento do domínio (o que é o sistema), em vez de combinar os dois em uma interface de classe.
  • Apoiar um estilo de pensamento objetivo que se aproxima dos modelos mentais das pessoas, e não o estilo de pensamento de classe.

Aqui está um bom artigo dos autores e aqui está um pequeno exemplo de implementação (.NET) se você quiser ver algum código. É muito mais simples do que parece, e parece muito natural.


0

Pode-se ouvir com frequência que o POO corresponde naturalmente à maneira como as pessoas pensam sobre o mundo. Mas eu discordo totalmente dessa afirmação (...)

Como ele é evangelizado em livros e em outros lugares por décadas, eu também não concordo. No entanto, acho que Nygaard e Dahl foram os que colocaram dessa maneira, e acho que eles estavam se concentrando em como era mais fácil pensar em projetar simulações em comparação com as alternativas da época.

(...) mas o foco do OOP é projetar classes individuais e suas hierarquias.

Essa afirmação entra em um território sensato, considerando o quão errados são os conceitos populares de POO e o quão sensível é a definição. Tenho mais de dez anos no campo, realizando trabalhos da indústria e pesquisas acadêmicas sobre prog. idiomas, e posso dizer que passei muitos anos desaprendendo o "mainstream OO" porque comecei a perceber o quão diferente (e inferior) é do que os criadores anteriores estavam buscando. Para um tratamento moderno e atualizado do assunto, eu me referiria ao recente esforço de W. Cook:

"Uma proposta para definições modernas e simplificadas de" objeto "e" orientação a objeto " http://wcook.blogspot.com.br/2012/07/proposal-for-simplified-modern.html

Diante desses problemas, como / por que aconteceu que a maneira atual de fazer POO se tornou tão popular?

Talvez a mesma razão pela qual os teclados QWERTY tenham se tornado populares ou a mesma razão pela qual o sistema operacional DOS tenha se tornado popular. As coisas simplesmente pegam carona em veículos populares, apesar de suas propriedades, e se tornam populares. E, às vezes, versões semelhantes, mas piores, de algo são consideradas a coisa real.

E o que, se alguma coisa, pode ser feito para destroná-lo?

Escreva um programa usando uma abordagem superior. Escreva o mesmo programa usando uma abordagem OO. Mostrar que o primeiro possui melhores propriedades do que o último em todos os aspectos significativos (propriedades do próprio sistema e propriedades de engenharia). Mostre que o programa escolhido é relevante e a abordagem proposta sustenta a alta qualidade das propriedades se aplicada a outros tipos de programas. Seja rigoroso em sua análise e use definições precisas e aceitas quando necessário.

Por fim, compartilhe suas descobertas conosco.


-1

Veja o Java: objetos são um tipo de gargalo de abstração, a maioria das "coisas" são estritamente subcomponentes de objetos ou usam objetos como subcomponentes. Os objetos devem ter vários propósitos o suficiente para uma camada de abstração inteira entre esses dois tipos de coisas - multi-propósito significa que não há uma metáfora que eles incorporem. Em particular, o Java torna os objetos (e classes) a única camada pela qual você chama / código de despacho. Essa quantidade de coisas que os objetos incorporam os torna, francamente, muito complexos. Qualquer descrição útil deles deve ser restrita a alguma forma especializada ou restrita.

As hierarquias de herança e interface são "coisas" que usam objetos como subcomponentes. Essa é uma maneira especializada de descrever objetos, não uma maneira de derivar uma compreensão geral dos objetos.

Pode-se dizer que "objetos" têm ou são muitas coisas porque são uma abstração de múltiplos propósitos que é mais ou menos universal em um "OO Langauge". Se eles são usados ​​para conter um estado local mutável ou para acessar algum estado externo do mundo, eles se parecem muito com um "substantivo".

Por outro lado, um objeto que representa um processo, por exemplo, "criptografar" ou "comprimir" ou "classificar", parece um "verbo".

Alguns objetos são usados ​​para sua função como um espaço para nome, por exemplo, um local para colocar a função "estática" em Java.

Estou inclinado a concordar com o argumento de que o Java é muito pesado em chamadas de método de objeto, com despacho no objeto. Provavelmente porque eu prefiro as classes de tipo de Haskell para controlar o envio. Essa é uma limitação de despacho e é um recurso do Java, mas não da maioria das linguagens ou mesmo da maioria dos idiomas OO.


-3

Testemunhei e participei de muitos debates on-line sobre OOP. Os proponentes do OOP geralmente não sabem escrever código processual adequado. É possível escrever código processual altamente modular. É possível separar código e dados e garantir que as funções possam gravar apenas em seu próprio armazenamento de dados. É possível implementar o conceito de herança usando código processual. Mais importante, o código processual é mais fino, mais rápido e mais fácil de depurar.

Se você criar módulos de arquivo único com convenções estritas de nomenclatura, o código processual será mais fácil de escrever e manter do que o OO e fará o mesmo ou mais e mais rápido. E não esqueça que, quando seu aplicativo é executado, é sempre processual, não importa quantas classes sejam exibidas no seu script.

Então você tem o problema de linguagens como PHP, que não são realmente orientadas a objetos e dependem de hacks para falsificar coisas como herança múltipla. Os figurões que influenciam a direção da linguagem transformaram o PHP em uma colcha de retalhos de regras inconsistentes que se tornaram grandes demais para o que ele pretendia inicialmente. Quando vejo desenvolvedores escreverem enormes classes de modelos para o que era uma linguagem de modelos processuais, não consigo deixar de sorrir.

Se você comparar código OO corretamente escrito com código de procedimento mal escrito, sempre chegará à conclusão errada. Muito poucos projetos justificam um design orientado a objetos. Se você é IBM e gerencia um grande projeto que precisa ser mantido por anos por vários desenvolvedores, vá para Orientado a Objetos. Se você estiver escrevendo um pequeno blog ou site de compras para um cliente, pense duas vezes.

Para responder à pergunta original, OOP é difícil porque não resolve dilemas da programação da vida real sem recorrer a soluções 100 vezes mais complicadas do que deveriam. Uma das soluções mais poderosas para muitos problemas de programação é o uso criterioso de dados globais. No entanto, os formandos das universidades da nova onda dirão que é um grande não-não. Os dados disponíveis globalmente são perigosos apenas se você é um coelho de programação desajeitado. Se você tiver um conjunto estrito de regras e convenções de nomenclatura adequadas, poderá ter todos os seus dados globais.

Deve ser um requisito obrigatório para qualquer programador orientado a objetos saber como escrever um aplicativo de xadrez no assembler para obter uma memória máxima disponível de 16K. Eles aprenderiam a cortar a gordura, reduzir a preguiça e gerar soluções engenhosas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.