Qual é o sentido do POO?

126

Até onde eu sei, apesar dos incontáveis ​​milhões ou bilhões gastos em educação, idiomas e ferramentas de POO, a POO não melhorou a produtividade do desenvolvedor ou a confiabilidade do software, nem reduziu os custos de desenvolvimento. Poucas pessoas usam OOP em qualquer sentido rigoroso (poucas pessoas aderem ou compreendem princípios como o LSP); parece haver pouca uniformidade ou consistência nas abordagens adotadas pelas pessoas para modelar domínios de problemas. Com demasiada frequência, a classe é usada simplesmente pelo seu açúcar sintático; coloca as funções para um tipo de registro em seu próprio pequeno espaço para nome.

Eu escrevi uma grande quantidade de código para uma ampla variedade de aplicativos. Embora tenha havido lugares em que a verdadeira subtipo substituível desempenhou um papel valioso no aplicativo, elas foram bastante excepcionais. Em geral, embora se fale muito de "reutilização", a realidade é que, a menos que um pedaço de código faça exatamente o que você deseja, há muito pouca "reutilização" econômica. É extremamente difícil projetar classes para serem extensíveis da maneira correta e , portanto, o custo da extensão é normalmente tão alto que a "reutilização" simplesmente não vale a pena.

Em muitos aspectos, isso não me surpreende. O mundo real não é "OO", e a idéia implícita no OO - de que podemos modelar coisas com alguma taxonomia de classe - me parece fundamentalmente defeituosa (posso sentar em uma mesa, um tronco de árvore, um capô de carro) , colo de alguém - mas nenhum deles é uma cadeira). Mesmo se mudarmos para domínios mais abstratos, a modelagem de OO geralmente é difícil, contra-intuitiva e, em última análise, inútil (considere os exemplos clássicos de círculos / elipses ou quadrados / retângulos).

Então, o que estou perdendo aqui? Onde está o valor do POO e por que todo o tempo e dinheiro falharam em melhorar o software?

DrPizza
fonte
11
Sua analogia é uma abstração muito alta para o "caso de uso" pretendido; mesa, toco de árvore, capô, colo de alguém são composições de moléculas, átomos, prótons, nêutrons, elétrons, formando uma área de superfície suficientemente grande para que seu bumbum repouse pela força da gravidade.
icelava 31/12/08
38
Não importa quantas vezes esse mesmo encadeamento seja iniciado, ele sempre desperta muito interesse (apesar do fato de que duplicatas geralmente não são toleradas aqui). E, claro, a resposta escolhida é sempre aquela que concorda com a opinião inicial do solicitante.
TM.
4
O problema com OOP é falha em colocá-lo em contexto. É excelente para alguns propósitos, nem todos os propósitos. É uma ótima ferramenta. É um péssimo evangelho.
Mike Dunlavey 31/12/08
16
Sinto muito, mas não posso deixar de sentir que você nunca programou usando qualquer tipo de linguagem. Aqui está o porquê: OOP é a base da operação para bibliotecas de componentes base em todos os ambientes modernos (Java, .NET, Python, Ruby - apenas para citar alguns dos principais). Todas essas bibliotecas básicas são reutilizadas diariamente, portanto, se isso não conta, não sei o que faz. Portanto, não me interpretem mal aqui, mas a reutilização de código, se for um fato - e extremamente comum! Eu não quero que isso pareça ofensivo de maneira alguma - apenas fazendo um ponto aqui.
Matthias Hryniszak 8/08/09
2
@ George Jempty: Foi Joel Spolsky em "Como a Microsoft perdeu a guerra da API" ( joelonsoftware.com/articles/APIWar.html ), a manchete da passagem é "Transmissões automáticas ganham o dia".
19410 GodsBoss

Respostas:

24

Não há evidências empíricas que sugiram que a orientação a objetos seja uma maneira mais natural de as pessoas pensarem no mundo. Há algum trabalho no campo da psicologia da programação que mostra que o OO não é de alguma forma mais adequado do que outras abordagens.

As representações orientadas a objetos não parecem ser universalmente mais utilizáveis ​​ou menos utilizáveis.

Não basta simplesmente adotar métodos OO e exigir que os desenvolvedores os usem, pois isso pode ter um impacto negativo na produtividade do desenvolvedor, bem como na qualidade dos sistemas desenvolvidos.

Que é de "Sobre a usabilidade das representações de OO", da Communications of the ACM, de outubro de 2000. Os artigos comparam principalmente o OO com a abordagem orientada ao processo. Há muitos estudos sobre como as pessoas que trabalham com o método OO "pensam" (Int. J. of Human-Computer Studies 2001, edição 54, ou Human-Computer Interaction 1995, vol. 10, tem um tema inteiro sobre os estudos OO), e pelo que li, não há nada que indique algum tipo de naturalidade na abordagem OO que a torne mais adequada do que uma abordagem processual mais tradicional.

Svend
fonte
18
Funciona bem. O que ele não pode fazer é forçar codificadores ruins a escrever um código bom. Há um tom periódico e chora contra isso por esse motivo.
caos
6
@elaus: o resumo está no meio. OOP é uma ferramenta no kit de ferramentas, não a única, e não há substituto para treinamento, experiência e julgamento.
Mike Dunlavey
44
Acho engraçado quando alguém posta uma "Pergunta" para argumentar sobre um ponto e aceita a primeira resposta que o sustenta, mesmo que haja perguntas com classificação mais alta apoiando o contrário. A natureza humana é legal.
Bill de Bill
3
@melaos, o resumo (pelo menos desses artigos) é que nada sugere que o OO seja uma maneira natural de pensar para as pessoas e, portanto, não é inerentemente superior a qualquer outra maneira de se construir programas.
Svend
6
@ Bill K: Foi uma das poucas respostas que forneceu citações, em vez de acenar com a mão e mera insistência de que OO "deve" ser melhor. Se a literatura referenciada apóia a noção de que OO não é uma melhoria ou benefício específico e, portanto, apóia minha posição original, não sei por que devo desconsiderá-la. Você pode fornecer referências semelhantes que contrariam meu OP?
DrPizza 30/11/2009
119

O mundo real não é "OO", e a idéia implícita no OO - que podemos modelar coisas com alguma taxonomia de classe - me parece fundamentalmente falho

Embora isso seja verdade e tenha sido observado por outras pessoas (veja Stepanov, inventor do STL), o resto não faz sentido. OOP pode ter falhas e certamente não é uma bala de prata, mas torna os aplicativos em larga escala muito mais simples, porque é uma ótima maneira de reduzir as dependências. Obviamente, isso é válido apenas para o design "bom" de OOP. Design desleixado não dará nenhuma vantagem. Porém, um design bom e dissociado pode ser modelado muito bem usando OOP e não bem usando outras técnicas.

Existem modelos muito melhores e mais universais ( o modelo do tipo Haskell vem à mente), mas esses também são frequentemente mais complicados e / ou difíceis de implementar com eficiência. OOP é uma boa troca entre extremos.

Konrad Rudolph
fonte
10
Acho interessante que isso tenha mais votos positivos do que a pergunta e a resposta aprovada combinadas.
Brad Gilbert
15
Acho o sistema de tipos de Haskell muito mais intuitivo que o OO.
axblount 23/10/08
4
@ Konrad: "mas torna as aplicações em larga escala muito mais simples" - hmmm, não sei se isso é verdade. Torna-os mais sustentáveis, no sentido de que uma coisa não deve quebrar outra, mas mais simples? Isso é um hrad um para engolir ...
Mitch Wheat
2
@ BradGilbert: é claro que o solicitante selecionou uma resposta que se alinha perfeitamente com a opinião em sua pergunta inicial. O que levanta a questão, por que se incomodar em perguntar se você já decidiu sua resposta?
TM.
2
@ Mitch: Eu diria que você não pode (a partir de hoje) escrever aplicativos de larga escala sem algum tipo de orientação a objetos. Em larga escala, aqui é> 1M LOC.
Konrad Rudolph
45

OOP não é sobre a criação de classes reutilizáveis, é sobre a criação de classes utilizáveis.

Brian Leahy
fonte
7
Agradável! E tão verdadeiro.
Toon Krijthe
1
Justo. Mas isso não resolve o problema "reinventar a roda", que é honestamente sério no desenvolvimento de software - em vez de ter uma biblioteca com N pares de olhos procurando falhas, temos N bibliotecas com um par de olhos tão. Existem tantas classes utilizáveis ​​que você pode criar antes de precisar reutilizá-las. E OOP, na minha opinião educada, é fundamentalmente falho exatamente nessa área - reutilização de código. Ele oculta os dados e os "casa" com métodos, tornando esses dados inacessíveis ou dificilmente interoperáveis.
amn
42

Com demasiada frequência, a classe é usada simplesmente pelo seu açúcar sintático; coloca as funções para um tipo de registro em seu próprio pequeno espaço para nome.

Sim, acho que isso também é muito prevalente. Isso não é programação orientada a objetos. É programação baseada em objetos e programação centrada em dados. Nos meus 10 anos de trabalho com OO Languages, vejo pessoas fazendo programação baseada em objetos. O OBP se decompõe muito rapidamente no IMHO, pois você está obtendo o pior de ambas as palavras: 1) Programação processual sem aderir à metodologia de programação estruturada comprovada e 2) OOP sem aderir à metodologia comprovada de OOP.

OOP feito corretamente é uma coisa bonita. Facilita a solução de problemas muito difíceis e, para os não iniciados (sem tentar parecer pomposo), pode parecer quase mágico. Dito isto, OOP é apenas uma ferramenta na caixa de ferramentas de metodologias de programação. Não é a metodologia de todos os fins. Por acaso, atende bem a grandes aplicativos de negócios.

A maioria dos desenvolvedores que trabalham em linguagens OOP estão utilizando exemplos de OOP feitos corretamente nas estruturas e tipos que eles usam no dia-a-dia, mas simplesmente não estão cientes disso. Aqui estão alguns exemplos muito simples: ADO.NET, Hibernate / NHibernate, Logging Frameworks, vários tipos de coleção de idiomas, a pilha ASP.NET, a pilha JSP, etc ... Tudo isso depende muito do OOP em suas bases de código.

Daniel Auger
fonte
32

A reutilização não deve ser uma meta da OOP - ou qualquer outro paradigma para esse assunto.

A reutilização é um efeito colateral de um bom design e nível adequado de abstração. O código consegue reutilizar fazendo algo útil, mas não fazendo tanto para torná-lo inflexível. Não importa se o código é OO ou não - reutilizamos o que funciona e não é trivial fazer nós mesmos. Isso é pragmatismo.

O pensamento de OO como uma nova maneira de reutilizar através da herança é fundamentalmente falho. Como você observa, as violações ao LSP são abundantes. Em vez disso, o OO é pensado adequadamente como um método de gerenciar a complexidade de um domínio de problema. O objetivo é a manutenção de um sistema ao longo do tempo. A principal ferramenta para conseguir isso é a separação da interface pública de uma implementação privada. Isso nos permite ter regras como "Isso só deve ser modificado usando ..." aplicadas pelo compilador, em vez de revisão de código.

Com isso, tenho certeza que você concorda, nos permite criar e manter sistemas extremamente complexos. Há muito valor nisso, e não é fácil fazer isso em outros paradigmas.

theschmitzer
fonte
3
verdade sobre reutilização e OO sendo preocupações separadas.
Dan Rosenstark
28

Aproximando-se de religiosos, mas eu diria que você está pintando uma imagem excessivamente sombria do estado da OOP moderna. Eu diria que ele realmente tem custos reduzidos, fez grandes projetos de software manejável, e assim por diante. Isso não significa que ele resolveu o problema fundamental da bagunça do software e não significa que o desenvolvedor médio é um especialista em OOP. Mas a modularização da função em componentes-objeto certamente reduziu a quantidade de código espaguete disponível no mundo.

Consigo pensar em dezenas de bibliotecas que são maravilhosamente reutilizáveis ​​e que economizam tempo e dinheiro que nunca podem ser calculados.

Mas, na medida em que o POO foi um desperdício de tempo, eu diria que é por falta de treinamento de programadores, agravado pela curva acentuada de aprendizado de aprender um mapeamento de POO específico da linguagem. Algumas pessoas "recebem" POO e outras nunca.

user2189331
fonte
2
Acabei de lhe dar um voto positivo que elevou você a mais de 2000 pontos - espero que continue. : P
Jason Bunting
5
É raro ver OOP sendo ensinado efetivamente.
Jon W
Sua resposta soa muito semelhante à dada pelos treinadores do Agile / Scrum quando perguntados se faz sentido - "é muito útil se você fizer o que é certo; se você falhar, deve estar fazendo errado". É fácil usar palavras como "reutilizável" e "sustentável", mas não é fácil quantificar essas qualidades no código real, nem existe uma receita que diga como escrever um bom OOP (apesar de milhares de livros tentarem fazê-lo) . Também temos o mau hábito de ignorar ostensivamente o hardware, o que leva a um desempenho horrível no altar, evitando a otimização prematura.
Tom
21

Eu acho que o uso de objetos de contexto opacos (HANDLEs no Win32, FILE * s em C, para citar dois exemplos conhecidos - inferno, HANDLEs vivem do outro lado da barreira do modo kernel, e realmente não são muito mais encapsulado que isso) também é encontrado no código processual; Estou lutando para ver como isso é algo específico para OOP.

HANDLEs (e o resto do WinAPI) é OOP! C não suporta muito bem o POO, portanto não há sintaxe especial, mas isso não significa que ele não use os mesmos conceitos. O WinAPI é, em todos os sentidos da palavra, uma estrutura orientada a objetos.

Veja, este é o problema de todas as discussões envolvendo OOP ou técnicas alternativas: ninguém é claro sobre a definição, todo mundo está falando sobre outra coisa e, portanto, nenhum consenso pode ser alcançado. Parece uma perda de tempo para mim.

Konrad Rudolph
fonte
1
Eu estava prestes a postar algo muito semelhante.
Brad Gilbert
Concordo que você pode usar conceitos de OOP sem sintaxe especial, mas, por outro lado, não acho que o WinAPI seja um bom exemplo de conceitos de OOP.
Lena Schimmel
14

É um paradigma de programação. Projetado para facilitar para nós, meros mortais, dividir um problema em pedaços menores e viáveis.

Se você não achar útil .. Não use, não pague pelo treinamento e seja feliz.

Eu, por outro lado, acho útil, então irei :)

Rob Cooper
fonte
14

Em relação à programação procedural direta, o primeiro princípio fundamental da OOP é a noção de ocultação e encapsulamento de informações. Essa ideia leva à noção da classe que separa a interface da implementação. Esses são conceitos extremamente importantes e a base para a criação de uma estrutura para pensar no design de programas de uma maneira diferente e melhor (eu acho). Você realmente não pode argumentar contra essas propriedades - não há compromisso e sempre é uma maneira mais limpa de modular as coisas.

Outros aspectos da POO, incluindo herança e polimorfismo, também são importantes, mas, como outros aludiram, esses são comumente usados ​​em excesso. ie: Às vezes as pessoas usam herança e / ou polimorfismo porque podem, não porque deveriam. São conceitos poderosos e muito úteis, mas precisam ser usados ​​com sabedoria e não são vantagens vencedoras automáticas do OOP.

Em relação à reutilização. Concordo que a reutilização é vendida em excesso para OOP. É um possível efeito colateral de objetos bem definidos, geralmente de classes mais primitivas / genéricas e é um resultado direto dos conceitos de encapsulamento e ocultação de informações. É potencialmente mais fácil de ser reutilizado porque as interfaces de classes bem definidas são simplesmente mais claras e um pouco auto-documentadas.

Tall Jeff
fonte
1
A reutilização é uma espécie de graal para desenvolvedores de software, não é, independentemente do paradigma que eles usam, seja OO, funcional ou qualquer outra coisa? Isso entra em conflito com os requisitos em constante mudança feitos no software e a questão parece ser a de fazer designs flexíveis.
Geoglifo
"noção da classe que separa a interface da implementação" --- Eu pensei que interfaces eram interfaces e classes eram implementações? Talvez eu seja apenas um pensador muito orientado para o processo, mas acho que é o polimorfismo, a variação no código e a uniformidade no uso, que é o pontapé inicial da OOP; Eu acho que "um monte de funções C" separa uma interface de uma implementação tão bem quanto "uma classe java". Talvez eu esteja tudo errado?
Jonas Kolker
2
@ Jonas - Para o seu "um monte de funções C" --- eu concordo que eles podem separar uma interface de uma implementação e, nesse ponto, está começando a ficar fora de controle. Se o exemplo continuar definindo uma estrutura C na qual a API opera, você basicamente criou o encapsulamento (especialmente se a API opera de maneira opaca na estrutura) ... e então é realmente OOP em C.
Tall Jeff
12

O problema com o POO é que ele foi vendido em excesso.

Como Alan Kay o concebeu originalmente, era uma ótima alternativa à prática anterior de ter dados brutos e rotinas globais.

Em seguida, alguns tipos de consultores de gestão se apegaram a ele e o venderam como o messias do software, e a academia e a indústria pareciam lemming.

Agora eles estão parecendo lemming depois que outras boas idéias estão sendo vendidas em excesso, como programação funcional.

Então, o que eu faria de diferente? Muito, e eu escrevi um livro sobre isso. (É fora de catálogo - Eu não entendo um centavo, mas você ainda pode obter cópias.) Amazon

Minha resposta construtiva é considerar a programação não como uma maneira de modelar as coisas no mundo real, mas como uma maneira de codificar os requisitos.

Isso é muito diferente e é baseado na teoria da informação (em um nível que qualquer um possa entender). Ele diz que a programação pode ser encarada como um processo de definição de linguagens, e a habilidade para fazer isso é essencial para uma boa programação.

Ele eleva o conceito de linguagens específicas de domínio (DSLs). Concorda enfaticamente com o DRY (não se repita). Dá um grande sinal de positivo para a geração de código. Isso resulta em software com estrutura de dados massivamente menor do que é típico para aplicativos modernos.

Ele procura revigorar a idéia de que o caminho a seguir está na inventividade e que mesmo idéias bem aceitas devem ser questionadas.

Mike Dunlavey
fonte
Legal. Como o livro está esgotado, você não gostaria de fornecer PDFs, certo? Amazon envia lentamente para Argentina ...
Dan Rosenstark
Suspeito que, em algum momento do processo, alguns codificadores bons tenham se tornado rapsódicos sobre o que eles poderiam fazer com o OOP, e alguém os ouviu e pensou que isso significava que todos poderiam e deveriam fazer o mesmo.
caos
@ Daniel: boa sugestão. Vou trabalhar nisso e ver se consigo anexá-lo ao meu blogspot. Você achará um pouco antiquado, porque foi em 94, mas os princípios não mudaram.
Mike Dunlavey #
1
@ Mike Dunlavey Prezado senhor, posso apoiar a curiosidade de @ yar em saber se há uma chance de ler / obter seu livro [pelo menos parcialmente] pela Internet? Como parece, a maneira como a especificação / implementação de software [componente] eficaz que você propõe / desenvolve se aproxima da que [reconheci recentemente] que gostaria de aprender ou ser ensinada (em oposição à maneira de 'carga' introduzida por escritos, mas dolorosamente ambíguos livros OO tradicionais). Agradecemos antecipadamente [e aplausos da Rússia :)].
Mlvljr
1
@mlvljr: OK. A maneira mais rápida pode ser apenas digitalizá-lo e criar um grande arquivo pdf. Vou ver se consigo chegar nos próximos dias. Não me deixe esquecer [sinceras condolências por acontecimentos recentes em Moscou e aplausos de Massachusetts encharcado].
Mike Dunlavey
11

HANDLEs (e o resto do WinAPI) é OOP!

Eles são, no entanto? Eles não são herdáveis, certamente não são substituíveis, eles não têm classes bem definidas ... Eu acho que eles ficam muito longe de "OOP".

Você já criou uma janela usando o WinAPI? Então você deve saber que define uma classe ( RegisterClass), cria uma instância dela ( CreateWindow), chama métodos virtuais ( WndProc) e métodos de classe base ( DefWindowProc) e assim por diante. O WinAPI ainda pega a nomenclatura do SmallTalk OOP, chamando os métodos de "mensagens" (Window Messages).

Os identificadores podem não ser herdáveis, mas existem finalem Java. Eles não têm falta de classe, são um espaço reservado para a classe: é isso que significa a palavra "manipular". Olhando para arquiteturas como MFC ou .NET WinForms, é óbvio que, exceto pela sintaxe, nada é diferente da WinAPI.

Konrad Rudolph
fonte
O WINAPI não é OOP. Apenas mostra uma maneira de escrever código processual extensível. Boas técnicas são boas, independentemente de serem POO ou não. Posso escrever programas WINAPI em C e usar as mesmas técnicas no meu próprio código, então acho que C é OOP.
bruceatk
3
Pode não ser o que Alan Kay tinha em mente (pesquise no google!), Mas é POO.
10288 Konrad Rudolph
11

Sim OOP não resolveu todos os nossos problemas, desculpe por isso. No entanto, estamos trabalhando em SOA que resolverá todos esses problemas.

Nat
fonte
4
Você não ouviu? SOA é o passado. Hoje é a computação em nuvem que será o nosso salvador.
DrPizza 17/09/08
Estou realmente me perguntando se suas respostas são irônicas ou não. I como ironia, mas geralmente está ficando rejeitada, isso me faz pensar ...
Lena Schimmel
Eu acho que este é irônico, e não vou votar. Mas também não vou votar! :
Yarik
A pergunta é bastante retórica, portanto, essa é uma resposta válida (e a melhor resposta).
Jeff Davis
10

OOP se presta bem à programação de estruturas internas de computadores, como "widgets" da GUI, onde, por exemplo, SelectList e TextBox podem ser subtipos de Item, que possui métodos comuns como "mover" e "redimensionar".

O problema é que 90% de nós trabalha no mundo dos negócios, onde trabalhamos com conceitos de negócios, como fatura, funcionário, trabalho e ordem. Eles não se prestam tão bem ao POO porque os "objetos" são mais nebulosos, sujeitos a alterações de acordo com a reengenharia dos negócios e assim por diante.

O pior caso é quando o OO é aplicado com entusiasmo aos bancos de dados, incluindo os "aprimoramentos" flagrantes de OO nos bancos de dados SQL - que são corretamente ignorados, exceto pelos noobs do banco de dados que assumem que devem ser o caminho certo para fazer as coisas porque são mais novos.

Tony Andrews
fonte
Isso tudo é verdade, mas ... talvez, o fato de o OOP possa simplificar ALGUNS aspectos não relacionados aos negócios de um aplicativo (como a implementação da interface do usuário) seja exatamente um dos principais motivos pelos quais um desenvolvedor (finalmente!) Possa passar mais tempo trabalhando nos negócios aspectos relacionados?
268 Yarik
10

Na minha experiência de revisar o código e o design dos projetos pelos quais passei, o valor do OOP não é totalmente percebido porque muitos desenvolvedores não conceituaram adequadamente o modelo orientado a objetos em suas mentes. Portanto, eles não programam com design OO, continuando frequentemente a escrever código processual de cima para baixo, tornando as classes um design bastante simples . (se você pode chamar isso de "design" em primeiro lugar)

É bastante assustador observar como os colegas pouco sabem sobre o que são uma classe ou interface abstrata e muito menos projetar adequadamente uma hierarquia de herança para atender às necessidades dos negócios.

No entanto, quando um bom design de OO está presente, é pura alegria ler o código e vê-lo naturalmente se encaixar em componentes / classes intuitivos. Eu sempre percebi a arquitetura e o design do sistema como projetar os vários departamentos e tarefas de uma empresa - todos estão lá para realizar um certo trabalho no grande esquema das coisas, emitindo a sinergia necessária para impulsionar a organização / sistema.

Isso, é claro, é bastante raro, infelizmente. Como a proporção de objetos físicos belamente projetados versus terrivelmente projetados no mundo, o mesmo pode ser dito sobre engenharia e design de software. Ter as boas ferramentas à disposição não necessariamente confere boas práticas e resultados.

icelava
fonte
1
Eu nunca atingi a fase de pura alegria processualmente ou POO durante a leitura de código. :)
bruceatk
1
Alegria pura, não, mas um pequeno sorriso, talvez?
Dan Rosenstark
9

Talvez um capô, um colo ou uma árvore não seja uma cadeira, mas todos são ISITÁVEIS.

Johnno Nolan
fonte
2
Você nunca teve que usar uma linguagem OO sem interfaces, não é? Você é sortudo.
finnw 28/09/08
Não, eles não são. São coisas que não foram projetadas para sentar, então acho que são verdadeiras à analogia, não teriam sido escritas para implementar a interface ISittable. Eles são de uma biblioteca de terceiros e, agora que você está escrevendo um projeto envolvendo um domínio que inclui sessão, você precisará escrever objetos do adaptador para envolvê-los e torná-los ISittable. Vejo? Não muito parecido com o mundo real.
ERIC
8

Eu acho que essas coisas do mundo real são objetos

Você faz?

Quais métodos uma fatura possui? Oh espere. Ele não pode pagar a si próprio, não pode enviar a si mesmo, não pode se comparar com os itens que o fornecedor realmente entregou. Não possui nenhum método; é totalmente inerte e não funcional. É um tipo de registro (uma estrutura, se você preferir), não um objeto.

Da mesma forma, as outras coisas que você menciona.

Só porque algo é real não o torna um objeto no sentido OO da palavra. Os objetos OO são um acoplamento peculiar de estado e comportamento que pode agir por conta própria. Isso não é algo abundante no mundo real.

DrPizza
fonte
2
Pegue qualquer máquina, dispositivo eletrônico ou coisa viva, todos esses são "acoplamentos de estado e comportamento".
TM.
1
Concordo que métodos como Send () ou Pay () não são "naturais" para faturas. Mas, por exemplo, e o valor total como um atributo derivado, mas INERENTE, de uma fatura? Não é um exemplo do que o OOP permite modelar de uma maneira muito "natural", mesmo para entidades da vida real totalmente inertes? Não uma grande conquista por si só, mas ainda assim ...
Yarik
@Yarik: Essas entidades "inertes" levam a um design baseado em objeto. Para mim, o único OO adequado é a Simulação, onde os objetos "podem agir por conta própria" , como afirma esta resposta. Se o OO é a única maneira tratável de realizar algo, tudo bem, mas, caso contrário, não podemos nos ater a algo mais simples e mais parecido com o problema que está sendo resolvido?
7

Eu tenho escrito código OO nos últimos 9 anos ou mais. Além de usar mensagens, é difícil para mim imaginar outra abordagem. O principal benefício que vejo totalmente alinhado com o que o CodingTheWheel disse: modularização. OO naturalmente me leva a construir meus aplicativos a partir de componentes modulares que possuem interfaces limpas e responsabilidades claras (ou seja, código altamente coeso, altamente acoplado e com uma clara separação de preocupações).

Acho que a OO se decompõe é quando as pessoas criam hierarquias de classe profundamente aninhadas. Isso pode levar à complexidade. No entanto, fatorar a fusionalidade comum em uma classe base e, em seguida, reutilizar isso em outras classes descendentes é uma coisa profundamente elegante, IMHO!

Sean Kearon
fonte
7

Em primeiro lugar, as observações são um tanto desleixadas. Não tenho dados sobre a produtividade de software e não tenho boas razões para acreditar que não está subindo. Além disso, como existem muitas pessoas que abusam de OO, o bom uso do OO não necessariamente causaria uma melhoria de produtividade, mesmo que o OO fosse a melhor coisa desde a manteiga de amendoim. Afinal, é provável que um cirurgião cerebral incompetente seja pior que nenhum, mas um competente pode ser inestimável.

Dito isto, o OO é uma maneira diferente de organizar as coisas, anexando código processual aos dados, em vez de fazer com que o código processual funcione nos dados. Isso deve ser pelo menos uma pequena vitória por si só, já que há casos em que a abordagem OO é mais natural. Afinal, não há nada que impeça alguém de escrever uma API processual em C ++ e, portanto, a opção de fornecer objetos torna a linguagem mais versátil.

Além disso, há algo que o OO faz muito bem: permite que o código antigo chame o novo código automaticamente, sem alterações. Se eu tenho um código que gerencia as coisas proceduralmente e adiciono um novo tipo de coisa semelhante, mas não idêntico a um anterior, preciso alterar o código procedural. Em um sistema OO, herdo a funcionalidade, mudo o que gosto e o novo código é usado automaticamente devido ao polimorfismo. Isso aumenta a localidade das mudanças, e isso é uma coisa boa.

A desvantagem é que o bom OO não é gratuito: requer tempo e esforço para aprendê-lo adequadamente. Como é um dos principais chavões, há muitas pessoas e produtos que fazem mal, apenas por fazê-lo. Não é mais fácil projetar uma boa interface de classe do que uma boa API de procedimentos, e há todos os tipos de erros fáceis de cometer (como hierarquias profundas de classe).

Pense nisso como um tipo diferente de ferramenta, não necessariamente geralmente melhor. Um martelo além de uma chave de fenda, digamos. Talvez acabemos saindo da prática da engenharia de software como sabendo qual chave usar para martelar o parafuso.

David Thornley
fonte
Eu gosto mais do seu último parágrafo.
Mike Dunlavey 31/12/08
6

@Sean

No entanto, fatorar a fusionalidade comum em uma classe base e, em seguida, reutilizar isso em outras classes descendentes é uma coisa profundamente elegante, IMHO!

Mas os desenvolvedores "procedimentais" fazem isso há décadas de qualquer maneira. A sintaxe e a terminologia podem ser diferentes, mas o efeito é idêntico. Há muito mais no POO do que "reutilizar funcionalidades comuns em uma classe base", e posso até dizer que isso é difícil de descrever como POO; chamar a mesma função de diferentes bits de código é uma técnica tão antiga quanto o próprio subprocedimento.

DrPizza
fonte
6

@Konrad

OOP pode ter falhas e certamente não é uma bala de prata, mas torna os aplicativos em larga escala muito mais simples, porque é uma ótima maneira de reduzir as dependências

Esse é o dogma. Não estou vendo o que torna a POO significativamente melhor nesse aspecto do que a programação procedural de antigamente. Sempre que faço uma chamada de procedimento, estou me isolando das especificidades da implementação.

DrPizza
fonte
6

Para mim, há muito valor na própria sintaxe OOP. Usar objetos que tentam representar coisas reais ou estruturas de dados geralmente é muito mais útil do que tentar usar várias funções simples (ou "flutuantes") diferentes para fazer a mesma coisa com os mesmos dados. Existe um certo "fluxo" natural para coisas com boa POO que só faz mais sentido ler, escrever e manter a longo prazo.

Não importa necessariamente que uma fatura não seja realmente um "objeto" com funções que ele mesmo possa executar - a instância do objeto pode existir apenas para executar funções nos dados sem precisar saber que tipo de dados realmente existe. A função "invoice.toJson ()" pode ser chamada com êxito sem precisar saber que tipo de dados é "fatura" - o resultado será Json, independentemente de ser proveniente de um banco de dados, XML, CSV ou mesmo outro objeto JSON . Com funções procedurais, você precisa repentinamente saber mais sobre seus dados e acabar com funções como "xmlToJson ()", "csvToJson ()", "dbToJson ()", etc. Isso acaba se tornando uma bagunça completa e uma ENORME dor de cabeça se você alterar o tipo de dados subjacente.

O objetivo do OOP é ocultar a implementação real abstraindo-a. Para atingir esse objetivo, você deve criar uma interface pública. Para facilitar seu trabalho ao criar essa interface pública e manter as coisas secas, você deve usar conceitos como classes abstratas, herança, polimorfismo e padrões de design.

Então, para mim, o verdadeiro objetivo principal do OOP é facilitar a manutenção e as alterações futuras do código. Mas mesmo além disso, ele pode realmente simplificar bastante as coisas quando feito corretamente de maneiras que o código processual nunca poderia. Não importa se não corresponde ao "mundo real" - a programação com código não está interagindo com objetos do mundo real. OOP é apenas uma ferramenta que torna meu trabalho mais fácil e rápido - eu vou fazer isso a qualquer dia.

Vance Lucas
fonte
5

@CodingTheWheel

Mas, na medida em que o POO foi um desperdício de tempo, eu diria que é por falta de treinamento de programadores, agravado pela curva acentuada de aprendizado de aprender um mapeamento de POO específico da linguagem. Algumas pessoas "recebem" POO e outras nunca.

Não sei se isso é realmente surpreendente, no entanto. Eu acho que abordagens tecnicamente sólidas (o LSP é a coisa mais óbvia) dificultam o uso , mas se não usarmos essas abordagens, o código fica quebradiço e inextensível (porque não podemos mais pensar nisso). E acho que os resultados contra-intuitivos que a OOP nos leva a tornam surpreendente que as pessoas não atendam.

Mais significativamente, como o software já é fundamentalmente muito difícil para humanos normais escreverem com confiabilidade e precisão, deveríamos realmente exaltar uma técnica que é ensinada de maneira consistente e que parece difícil de aprender? Se os benefícios foram claros, pode valer a pena perseverar, apesar da dificuldade, mas esse não parece ser o caso.

DrPizza
fonte
O "treinamento adequado" deve ser muito longo, abstrato e complexo nos dias de hoje. Eu sei: eu ensino programação. Décadas atrás, muitas pessoas podiam aprender a fazer algum tipo de programação. Eu acho que isso não é mais verdade.
5

@Jeff

Em relação à programação procedural direta, o primeiro princípio fundamental da OOP é a noção de ocultação e encapsulamento de informações. Essa ideia leva à noção da classe que separa a interface da implementação.

Qual tem a implementação mais oculta: iostreams de C ++ ou FILE * s de C?

Eu acho que o uso de objetos de contexto opacos (HANDLEs no Win32, FILE * s em C, para citar dois exemplos conhecidos - inferno, HANDLEs vivem do outro lado da barreira do modo kernel, e realmente não são muito mais encapsulado que isso) também é encontrado no código processual; Estou lutando para ver como isso é algo específico para OOP.

Suponho que isso possa ser parte do motivo pelo qual estou lutando para ver os benefícios: as partes obviamente boas não são específicas para o POO, enquanto as partes específicas para o POO não são obviamente boas! (isso não significa que eles sejam necessariamente ruins, mas que eu não vi a evidência de que eles são amplamente aplicáveis ​​e consistentemente benéficos).

DrPizza
fonte
5

No único blog de desenvolvimento que li, por aquele cara do Joel-On-Software-Founder-of-SO, li há muito tempo que o OO não leva ao aumento da produtividade. O gerenciamento automático de memória sim. Legal. Quem pode negar os dados?

Ainda acredito que OO é não-OO o que programar com funções é programar tudo em linha.

(E eu deveria saber, como comecei com GWBasic.) Quando você refatora o código para usar funções, variable2654torna-se variable3o método em que você está. Ou, melhor ainda, ele tem um nome que você pode entender e se a função é curta , é chamado value e é suficiente para uma compreensão completa.

Quando o código sem funções se torna código com métodos, você pode excluir quilômetros de código.

Quando você refatorar código para ser verdadeiramente OO, b, c, q, e Zse tornar this, this, thise this. E como não acredito em usar a thispalavra - chave, você pode excluir quilômetros de código. Na verdade, você consegue fazer isso mesmo se usar this.



Eu não acho que OO é uma metáfora natural.

Também não acho que a linguagem seja uma metáfora natural, nem os "cheiros" de Fowler são melhores do que dizer "esse código tem um gosto ruim". Dito isto, acho que o OO não é sobre metáforas naturais e as pessoas que pensam que os objetos simplesmente surgem em você estão basicamente perdendo o objetivo. Você define o universo de objetos e melhores universos de objetos resultam em códigos mais curtos, fáceis de entender, que funcionam melhor ou todos eles (e alguns critérios que estou esquecendo). Eu acho que as pessoas que usam os objetos naturais dos clientes / domínio como objetos de programação estão perdendo o poder de redefinir o universo.

Por exemplo, quando você faz um sistema de reservas aéreas, o que você chama de reserva pode não corresponder a uma reserva legal / comercial.



Alguns dos conceitos básicos são ferramentas muito legais

Eu acho que a maioria das pessoas exagera com a coisa toda "quando você tem um martelo, todas são pregos". Penso que o outro lado da moeda / espelho é igualmente verdadeiro: quando você tem um dispositivo como o polimorfismo / herança, começa a encontrar usos onde ele se encaixa como uma luva / meia / lente de contato. As ferramentas do OO são muito poderosas. Penso que a herança única é absolutamente necessária para que as pessoas não se deixem levar, meu próprio software de herança múltipla não resiste.



Qual é o sentido do POO?

Eu acho que é uma ótima maneira de lidar com uma base de código absolutamente enorme. Eu acho que ele permite que você organize e reorganize seu código e fornece uma linguagem para fazer isso (além da linguagem de programação em que você está trabalhando), e modula o código de uma maneira bastante natural e fácil de entender.

OOP está destinado a ser mal interpretado pela maioria dos desenvolvedores

Isso ocorre porque é um processo de abrir os olhos como a vida: você entende OO cada vez mais com a experiência e começa a evitar certos padrões e a empregar outros à medida que fica mais sábio. Um dos melhores exemplos é que você para de usar a herança para classes que não controla e prefere o padrão Fachada .



Em relação ao seu mini-ensaio / pergunta

Eu queria mencionar que você está certo. Reutilização é um sonho, na maior parte. Aqui está uma citação de Anders Hejilsberg sobre esse tópico (brilhante) daqui :

Se você pedir aos programadores iniciantes que escrevam um controle de calendário, eles geralmente pensam: "Ah, eu vou escrever o melhor controle de calendário do mundo! Será polimórfico com relação ao tipo de calendário. Ele terá exibidores, e mungers, e isso, aquilo e aquilo outro ". Eles precisam enviar um aplicativo de calendário em dois meses. Eles colocam toda essa infraestrutura no controle e passam dois dias escrevendo sobre um aplicativo de calendário de baixa qualidade. Eles pensam: "Na próxima versão do aplicativo, farei muito mais".

No entanto, uma vez que eles começam a pensar em como vão implementar todas essas outras concretizações de seu design abstrato, o design está completamente errado. E agora eles se pintaram em um canto, e eles têm que jogar tudo fora. Eu tenho visto isso repetidamente. Eu acredito muito em ser minimalista. A menos que você realmente resolva o problema geral, não tente criar uma estrutura para resolver uma questão específica, porque você não sabe como deve ser a estrutura.

Yar
fonte
4

Você já criou uma janela usando o WinAPI?

Mais vezes do que eu gostaria de lembrar.

Você deve saber que define uma classe (RegisterClass), cria uma instância (CreateWindow), chama métodos virtuais (WndProc) e métodos de classe base (DefWindowProc) e assim por diante. O WinAPI ainda pega a nomenclatura do SmallTalk OOP, chamando os métodos de "mensagens" (Window Messages).

Além disso, você também saberá que ele não envia sua própria mensagem, o que é um grande vazio. Ele também possui subclassificação de baixa qualidade.

Os identificadores podem não ser herdáveis, mas há final em Java. Eles não têm falta de classe, são um espaço reservado para a classe: é isso que significa a palavra "manipular". Olhando para arquiteturas como MFC ou .NET WinForms, é óbvio que, exceto pela sintaxe, nada é diferente da WinAPI.

Eles não são herdáveis ​​na interface ou na implementação, são minimamente substituíveis e não são substancialmente diferentes do que os codificadores de procedimentos vêm fazendo desde sempre.

É realmente isso? Os melhores bits de OOP são apenas ... código processual tradicional? Esse é o grande problema?

DrPizza
fonte
Você deve se lembrar que a interface do Win32 foi basicamente uma reimplementação do Win16. Que foi projetado mais de duas décadas atrás.
Brad Gilbert
Quando eu estava aprendendo a programar na faculdade, principalmente em C, mas também em alguns outros idiomas, aprendemos algumas idéias básicas e expostas a algumas plataformas, mas entendeu-se que a responsabilidade geral de criar designs, estruturas, práticas recomendadas, etc. depende de nós no local de trabalho. Aprendemos técnicas, não visões de mundo. Com o OO, você precisa aprender uma religião antes de poder fazer algo útil, e isso determina completamente como você vê as soluções. Eu não acho isso realmente apropriado.
4

Concordo totalmente com a resposta de InSciTek Jeff , apenas adicionarei os seguintes refinamentos:

  • Escondimento e encapsulamento de informações: crítico para qualquer código de manutenção. Isso pode ser feito com cuidado em qualquer linguagem de programação, não requer recursos de OO, mas fazê-lo tornará seu código um pouco parecido com OO.
  • Herança: Há um domínio de aplicativo importante para o qual todos os relacionamentos OO são do tipo e contém um, são perfeitamente adequados: Interfaces Gráficas do Usuário. Se você tentar criar GUIs sem suporte ao idioma OO, acabará criando recursos semelhantes a OO de qualquer maneira, e é mais difícil e mais propenso a erros sem o suporte ao idioma. Glade (recentemente) e X11 Xt (historicamente), por exemplo.

O uso de recursos OO (especialmente hierarquias abstratas profundamente aninhadas), quando não faz sentido, é inútil. Mas para alguns domínios de aplicativo, realmente há um ponto.

Liudvikas Bukys
fonte
Sim, eu acho que você deve usar OOP para objetos, programação funcional para funções ...
Svante
4

Acredito que a qualidade mais benéfica do OOP é ocultar / gerenciar dados. No entanto, existem muitos exemplos em que OOP é mal utilizado e acho que é aí que entra a confusão.

Só porque você pode transformar algo em um objeto não significa que você deveria. No entanto, se isso tornar seu código mais organizado / mais fácil de ler, você definitivamente deveria.

Um ótimo exemplo prático em que o POO é muito útil é com uma classe "produto" e objetos que eu uso em nosso site. Como cada página é um produto e cada produto tem referências a outros produtos, pode ficar muito confuso sobre a qual produto os dados a que você se refere. Essa variável "strURL" é o link para a página atual, a página inicial ou a página de estatísticas? Claro que você pode criar todos os tipos de variáveis ​​diferentes que se referem às mesmas informações, mas proCurrentPage-> strURL é muito mais fácil de entender (para um desenvolvedor).

Além disso, anexar funções a essas páginas é muito mais limpo. Eu posso fazer proCurrentPage-> CleanCache (); Seguido por proDisplayItem-> RenderPromo (); Se eu apenas chamasse essas funções e assumisse que os dados atuais estavam disponíveis, quem sabe que tipo de mal iria ocorrer. Além disso, se eu tivesse que passar as variáveis ​​corretas para essas funções, volto ao problema de ter todos os tipos de variáveis ​​para os diferentes produtos disponíveis.

Em vez disso, usando objetos, todos os dados e funções do meu produto são agradáveis, limpos e fáceis de entender.

Contudo. O grande problema com OOP é quando alguém acredita que TUDO deve ser OOP. Isso cria muitos problemas. Eu tenho 88 tabelas no meu banco de dados. Eu tenho apenas 6 aulas, e talvez eu deva ter 10. Eu definitivamente não preciso de 88 aulas. Na maioria das vezes, o acesso direto a essas tabelas é perfeitamente compreensível nas circunstâncias em que eu a uso, e o OOP tornaria realmente mais difícil / entediante acessar a funcionalidade principal do que está ocorrendo.

Acredito que um modelo híbrido de objetos é útil e processual, onde prático é o método mais eficaz de codificação. É uma pena que tenhamos todas essas guerras religiosas em que as pessoas defendem o uso de um método em detrimento dos outros. Ambos são bons e ambos têm o seu lugar. Na maioria das vezes, existem usos para ambos os métodos em todos os projetos maiores (em alguns projetos menores, um único objeto ou alguns procedimentos podem ser tudo o que você precisa).

Jeff Davis
fonte
3

Não me importo tanto com a reutilização quanto com a legibilidade. O último significa que seu código é mais fácil de alterar. Só isso vale em ouro na construção de software.

E o OO é uma maneira bastante eficaz de tornar seus programas legíveis. Reutilizar ou não reutilizar.

Frederick The Fool
fonte
2

"O mundo real não é" OO ","

Realmente? Meu mundo está cheio de objetos. Eu estou usando um agora. Eu acho que ter "objetos" de software modelar os objetos reais pode não ser uma coisa tão ruim.

Projetos de OO para coisas conceituais (como Windows, não janelas do mundo real, mas os painéis de exibição no monitor do meu computador) geralmente deixam muito a desejar. Mas para coisas do mundo real, como faturas, pedidos de remessa, pedidos de seguro e outras coisas, acho que essas coisas do mundo real são objetos. Eu tenho uma pilha na minha mesa, então elas devem ser reais.

S.Lott
fonte
2

O objetivo do OOP é fornecer ao programador outros meios para descrever e comunicar uma solução para um problema no código para máquinas e pessoas. A parte mais importante disso é a comunicação com as pessoas. OOP permite que o programador declare o que eles significam no código por meio de regras aplicadas na linguagem OO.

Ao contrário de muitos argumentos sobre este tópico, os conceitos de OOP e OO são difundidos em todo o código, incluindo código em linguagens não OOP, como C. Muitos programadores avançados não OO aproximam os recursos de objetos, mesmo em linguagens não OO.

Ter OO embutido na linguagem apenas fornece ao programador outro meio de expressão.

A maior parte da escrita de código não é a comunicação com a máquina, essa parte é fácil, a maior parte é a comunicação com programadores humanos.

Bernard Igiri
fonte