Executando verificação de segurança...
-9

POO e Padrões de Projetos são lixo

Nota:

Infelizmente a regra de negócio do TabNews não me deixa responder todos os comentários. Por isso vou responder por aqui. Mais abaixo você encontrará o post original.

Como o post tem limite de caracteres, coloquei os comentários aqui

smiley

POO e padrões de projetos muitas vezes não são a melhor solução para um problema.

Surge a pergunta: em que situação POO é a melhor solução? E para qual problema?

Simula é considerada a primeira linguagem orientada a objetos e muitas linguagens OO foram influenciadas por essa linguagem, incluindo Java. Mas não entendi o que tem a ver com o post em si?

É lixo para uns, luxo para outros.

Concordo. Escrevi esse post para gerar essa discussão, porque na cultura de programação tem essa ideia de que POO é útil para alguns casos. Mas na minha opinião e experiência não vejo utilidade. E outros programadores, que coloquei alguns links no post, também compartilham dessa opinião.

kht

São ferramentas que têm sua utilidade.

Surge a pergunta: em que situação POO é útil?

POO, definida por Alan Kay, não é o foco da minha argumentação. Como ele mesmo já disse, o foco são mensagens e não objetos, então deveria se chamar Message Oriented Programming.

uriel

Obrigado por concordar. Realmente, o objetivo do título era chamar a atenção mesmo e tentar gerar uma discussão interessante sobre o tema. Visto que é tão comum pessoas defenderem POO, resolvi mostrar um ponto de vista diferente. Mas pelos downvotes percebi que as pessoas não têm interesse nisso.

POO nem padrão tem. Ninguém sabe a definição dela!

Verdade. Quando pesquisei sobre POO para escrever este post, vi isso também. Muitos não conseguem definir ou acham que tem várias definições de POO. Na minha opinião, o que faz mais sentido é a agregação de dados e operações na mesma estrutura, ou seja, objeto.

RecursiveError

desempenho depende da implementação.

tem seus próprios pontos fracos e fortes, nenhum dos links critica OO em si, apenas apresenta soluções mais adequadas para um problema específico.

Os três links que eu coloquei no post mostram que a implementação OO tem pior desempenho que DOD. O terceiro link é mais sutil, mas ele menciona no vídeo.

OO não é bala de prata, obviamente não serve para tudo.

Então para que serve OO? Quando ela é útil? Qual problema ela resolve?

DoD não substitui OO, na verdade eles são ótimos juntos.

Os dois conceitos são completamente opostos. OO junta dado e operação em uma estrutura. DoD separa os dois.

onde isso?

Nos livros que mencionei. Eles escreveram heurísticas para escrever código OO melhor.

problemas de 1994 não são os mesmos de hoje.

Os livros são de 1996, 2004, 2016 e 2017. Afinal, quais problemas não são mais os mesmos de hoje?

não existe explicitamente OO, imagino que você esteja falando de Java/C#/C++

Estou falando da OO mais comum, que está presente em Java e C++. É o que menciona várias vezes no post.

Erlang usa a definição de Alan Kay

Exatamente, mas não é essa definição que estou argumentando contra.

Não é o OO que deixa complexo, porque não é o OO que resolve o problema, quem resolve é você, desenvolvedor, é sua função como Dev de levantar requisitos, é sua função como Dev colocar os trade-offs de cada implementação na balança, é sua função como Dev ser um Dev.

Exatamente, e qual é a vantagem de usar POO?

os códigos "Não-OO" que você citou são ótimos exemplos do bom uso de OO, eles usam conceitos desse paradigma, porque têm utilidade e são simples se usados de forma correta, que nem qualquer coisa. (link)

Não, eles não usam OO. O link que você colocou mostra que na versão 2 do kernel do Linux teve alguns conceitos de OO no passado, há mais de 10 anos. O artigo apenas cita que encontrou esses conceitos no kernel mas não explica em detalhes quais as vantagens. Mas hoje o kernel está na versão 6 e o código já está bem diferente do que era.

código que refatorou é um código feito para aprendizado desses conceitos

Então porque não foi usado um problema que realmente precisasse de Design Patterns? Mesmo que seja de aprendizado, eu espero que seja algo relevante para a solução do problema. E esse é um problema em geral com vários posts e vídeos na internet, eles dão exemplos muito simples, como: Cachorro herda de Animal. Seria mais vantajoso mostrar exemplos reais em projetos grandes de como foi implementada a solução e analisar os trade-offs de outras soluções. Na minha versão o código ficou mais simples sem a necessidade do Design Pattern.

isso aqui é só meteção de loko, porque que Java e C++ é popular, ent? meter esse papo em TI não cola, C++ com quase 4 décadas de história .... se não tivesse vantagem Java taria morto já.

Em uma palavra: Marketing

Se fosse tão bom não haveria necessidade de criar outras linguagens de programação.

os "não-OO" aí de cima que diga né

Não entendi.


Segue o post original:

Quando comecei minha carreira em programação, aprendi que POO é uma ferramenta e, como toda ferramenta, tem seu lugar para resolver um problema.

A princípio parecia fazer sentido, mas à medida que fui adquirindo mais experiência em programação, percebi que POO não traz nenhum benefício. É por isso que escrevi para ignorar POO.

A primeira razão para ignorar OOP é que isso leva a um desempenho ruim:

Outra razão é que vários livros tentam corrigir POO:

Esses livros mostram que POO é falho visto que
eles fornecem diretrizes para escrever melhor código OO.
Todos os três livros combinados têm cerca de 1.200 páginas de heurísticas!
Tente se lembrar de tudo isso!

Michael Feathers escreveu em seu blog dizendo que seu livro "Trabalho Eficaz com Código Legado"
deveria se chamar "Trabalho Eficaz com Código Orientado a Objetos".

Eu me pergunto por que não existe um livro para trabalhar com código funcional ou procedural legado.
Provavelmente porque não existe uma técnica secreta, é muito simples de lidar, então não precisa de um livro para isso.

Outra razão é que linguagens modernas, como Zig, Go e Erlang, não adotam explicitamente a POO e não a incentivam. Algumas linguagens mais antigas, como Java, C# e C++, estão se afastando da POO através da implementação de recursos funcionais.

No meu primeiro post, mencionei que Rust não adota POO explicitamente, mas a documentação oficial mostra que sim. No entanto, parece que não é muito divulgado.

Alguns defensores da POO afirmam que a POO é mais adequada para softwares grandes e complexos. Esta afirmação é um absurdo completo. Existem muitos projetos não-OO grandes, complexos e bem-sucedidos: Git, Linux, Redis, Nginx, Postgres e SQLite. Você pode escrever software grande, complexo e bem-sucedido em qualquer paradigma, até mesmo assembly!

Outros defensores afirmam que POO é melhor para código de interface gráfica.
Mas esta não é a única abordagem para escrever código de interface gráfica, como
interface gráfica de modo imediato.

Uma das afirmações mais irritantes é quando alguém critica um código OO e diz que o desenvolvedor
fez mais complicado do que precisa e não é culpa da POO.
Os desenvolvedores podem projetar soluções excessivamente complicadas, mas acredito firmemente
que POO leva a soluções excessivamente complicadas.

Para finalizar esta seção, gostaria de dar um exemplo onde o código procedural é muito mais simples que o código OO. Martin Fowler, que escreveu o livro Refactoring, reescreveu o exemplo da Loja de Vídeo em JavaScript, onde calcula a fatura do cliente e imprime o extrato.

Na primeira versão, ele escreveu em Java. O código inicial tem três classes e 88 linhas de código. Tudo isso cabe facilmente em 42 linhas de JavaScript. Se você adicionar tipagem, aumenta para 57, mas ainda menos que Java.

Você pode até traduzi-lo para C, que, apesar de ser mais antigo que Java, tem uma certa simplicidade que falta ao Java.


Já que já discuti que POO é lixo. Vamos para Padrões de Projeto. Como o título diz: “Padrões de Projetos: Soluções Reutilizáveis de Software Orientados a Objetos” é específico para POO.

O único propósito dos padrões de projeto é corrigir deficiências na linguagem, especialmente C++ e Java.
Os autores concordam que alguns padrões não fazem sentido em outra linguagem porque possuem mecanismos melhores para resolver um problema.
O trecho do livro:

...alguns de nossos padrões são suportados diretamente pelas linguagens orientadas a objetos menos comuns. O CLOS possui vários métodos, por exemplo, que diminuem a necessidade de um padrão como Visitor (página 331). Na verdade, existem diferenças suficientes entre Smalltalk e C++ para significar que alguns padrões podem ser expressos mais facilmente em uma linguagem do que em outra.
e a maioria dessas linguagens existia antes de Java e C++, que são as linguagens alvo do livro.

Além disso, Peter Norvig apontou que
"16 dos 23 padrões têm uma implementação qualitativamente mais simples em Lisp ou Dylan".
Outra postagem interessante mostra como Clojure simplifica esses padrões.

Se C++ ou Java tivessem sido baseados em Lisp, então o livro de padrões nunca existiria.

A escolha da linguagem de programação é importante porque influencia o ponto de vista de cada um. Nossos padrões assumem recursos de linguagem de nível Smalltalk/C++, e essa escolha determina o que pode e o que não pode ser implementado facilmente. Se assumissemos linguagens procedurais, poderíamos ter incluído padrões de design chamados “Herança”, “Encapsulação” e “Polimorfismo”.

Herança, encapsulamento e polimorfismo não são padrões!
Eles são simplesmente recursos de linguagem. Eles não resolvem um problema recorrente.

Eu também acredito
que Padrões de Projeto não descrevem problemas reais
mas problemas fictícios da mentalidade de design da POO.

Algumas citações do livro explicam um pouco sobre o design da POO em geral.

A parte difícil do design orientado a objetos é decompor um sistema em objetos. A tarefa é difícil porque muitos fatores entram em jogo: encapsulamento, granularidade, dependência, flexibilidade, desempenho, evolução, capacidade de reutilização e assim por diante. Todos eles influenciam a decomposição, muitas vezes de formas conflitantes.

As metodologias de design orientadas a objetos favorecem muitas abordagens diferentes. Você pode escrever uma declaração de problema, destacar os substantivos e verbos e criar classes e operações correspondentes. Ou você pode se concentrar nas colaborações e responsabilidades do seu sistema. Ou você pode modelar o mundo real e traduzir os objetos encontrados durante a análise em design. Sempre haverá desacordo sobre qual abordagem é a melhor.

Esta é a falha fundamental do POO. Supõe que devemos
projetar o código em torno de objetos, não da solução.
Isso leva a um design estranho e a uma estrutura complexa, semelhante a este projeto satírico
FizzBuzzEnterpriseEdition.

Os padrões de projeto resolvem muitos dos problemas diários enfrentados pelos designers orientados a objetos.

Eles enfrentam esses problemas porque POO é lixo.

A estrutura de tempo de execução de um programa orientado a objetos geralmente tem pouca semelhança com sua estrutura de código. A estrutura do código é congelada em tempo de compilação; consiste em classes em relacionamentos de herança fixa. A estrutura de tempo de execução de um programa consiste em redes de objetos em comunicação que mudam rapidamente. Na verdade, as duas estruturas são em grande parte independentes.

Com tanta disparidade entre as estruturas de tempo de execução e de compilação de um programa, fica claro que o código não revelará tudo sobre como um sistema funcionará. A estrutura de tempo de execução do sistema deve ser imposta mais pelo designer do que pela linguagem. Os relacionamentos entre objetos e seus tipos devem ser projetados com muito cuidado, pois determinam quão boa ou ruim é a estrutura de tempo de execução.

Esta é outra razão pela qual a OOP leva a um design ruim. Torna mais difícil entender o programa lendo-o porque é uma rede de objetos comunicantes.

Não consideramos esta coleção de padrões de projeto completa e estática; é mais uma gravação de nossos pensamentos atuais sobre design.

Então, por que não há uma segunda edição depois de 30 anos?

Para finalizar esta seção, refatorei um jogo simples.
O jogo fez uso intenso do padrão observer. Então, como demonstração, removi as camadas indiretas e simplifiquei o código geral. No final, o padrão observer era desnecessário.

Você pode comparar você mesmo, o código original e minha versão refatorada. Então, veja qual é mais fácil de ler e entender.

Conclusão

POO tornou-se amplamente utilizado devido à popularidade de C++ e Java, não porque seja inerentemente bom. POO não oferece nenhum benefício que as pessoas dizem. O código procedural é tão flexível, modular e reutilizável quanto OO. A ideia de que POO é de alguma forma melhor nisso é um absurdo completo.

Tenha cuidado com qualquer pessoa que esteja “vendendo” padrões para você. Certifique-se de que eles sirvam a um propósito e resolvam seu problema. Não se esqueça de que as estruturas de dados e os algoritmos são muito mais fundamentais do que qualquer padrão de design.

A principal lição desta postagem é:

Se você ignorar POO, seu código ficará mais simples.

Para finalizar meu caso contra POO, selecionei uma lista de links que discutem um pouco sobre como a POO é ruim:

Carregando publicação patrocinada...
5

concordo com a parte de que existem problemas, não existe bala de prata na programação, mas tem muito coisa equivocada no seu post, o maior problema no seu argumento é colocar o paradigma, implementação e padrão de mercado com se fosse a mesma coisa, vamos por parte:

  1. "A primeira razão para ignorar OOP é que isso leva a um desempenho ruim", desenpenho depende de implementação.
  2. DoD de fato é uma tecnica eficiente pra lidar com dados, tem seus proprios pontos fracos e fortes, nenhum dos links critica OO em si, apenas apresenta soluçoes mais adequadas para um problema especifico, o que é algo normal, OO n é bala de prata, obviamente n serve pra tudo
  3. DoD não subistitue OO, na verdade eles são otimos juntos

"outra razão é que vários livros tentam corrigir POO"
onde isso? ele não corrigem OO, eles apresentam sugestões para resolver problemas modernos, coisas atualizam, problemas de 1994 não são os mesmos de hoje.

"não adotam explicitamente a POO"
não existe explicitamente OO, imagino que voce esteja falando de Java/C#/C++ aqui, Zig, Go e Rust não tem esse estilo porque C++ ja deixou mais do que claro que implementar essas features pode acabar limitando linguagens de sistema, aqui estamos falando de regras de inicilização, vtables,lifetime,...etc, detalhes de implementação de cada lang, não de OO.
(e Erlang usa a definição de Alan Kay, é bem mais fechada que a definição do GoF)

"Alguns defensores da POO afirmam que a POO é mais adequada para softwares grandes e complexos. Esta afirmação é um absurdo completo"
SIM, EXATAMENTE ISSO, DECLARAÇÃO PERFEITA.

"Existem muitos projetos não-OO grandes, complexos e bem-sucedidos: Git, Linux, Redis, Nginx, Postgres e SQLite."
.....

"Você pode escrever software grande, complexo e bem-sucedido em qualquer paradigma, até mesmo assembly!"
SIM, EXATAMENTE ISSO, DECLARAÇÃO PERFEITA

essa linha do meio não da, se fosse só o inicio e o final ficaria simplismente perfeito, sabe porque? pq isso aqui é vdd "desenvolvedor
fez mais complicado do que precisa e não é culpa da POO."
Não é o OO que deixa complexo, pq não é o OO que resolve o problema, quem resolve é voce, desevolvedor, é sua função como Dev de levantar requisitos, é sua função como Dev colocar os tradeoffde cada implementação na balança, é sua função como Dev ser um Dev.

os codigos "Não-OO" que vc citou, são otimos exemplos do bom uso de OO, eles usam conceitos desse paradigma, pq tem utilidade e é simples se usado de forma correta, que nem qualquer coisa
(https://lwn.net/Articles/444910/)

em Padrões de Projeto eu não vou nem comentar, cai no mesmo que eu disse acima sobre a obrigração como Dev, voce que tem que avaliar e modificar da melhor forma para sua aplicação, esses livros de Padrões de Projeto são sugestoes, não regras.
(e o codigo que refatorou é um codigo feito para aprendizado desses conceitos, não é o escopo do projeto o uso de outras tecnica)

"POO tornou-se amplamente utilizado devido à popularidade de C++ e Java, não porque seja inerentemente bom."

isso aqui é só meteção de loko, porque que Java e C++ é popular ent? meter esse papo em TI não cola, C++ com quase 4 decadas de historia, Java vire e mexe quebra a retrocompatibilidade com alguma coisa, é a desculpa perfeita pra troca de lang

se não tivesse vantagem Java taria morto ja.

"POO não oferece nenhum benefício que as pessoas dizem. O código procedural é tão flexível, modular e reutilizável quanto OO."
os "não-OO" ai de cima que diga né

2

Eu não diria que são um lixo completo, apenas que são ferramentas que têm sua utilidade, mas que ao longo do tempo foram extremamente abusadas (ou seja, usadas em contextos inadequados, nos quais não eram a melhor solução). O fato de terem sido moda por um longo período ajudou no abuso, e na percepção geral de que seriam ruins pra tudo.

Por exemplo, um erro comum ao usar design patterns é pegar um padrão e tentar encaixar no código de qualquer jeito. Sendo que o correto é o contrário: vc avalia o problema e verifica qual padrão seria mais adequado para resolvê-lo (em outras palavras, vê qual é o problema e procura a solução, em vez de pegar uma solução e tentar encaixá-la no problema). Neste caso, o problema é do padrão em si, ou de quem tentou usá-lo errado?

Pra complementar, seguem alguns links relevantes:

2

Esse bait no titulo do texto vai ser um probema aqui no tabnews.

Gente que não entende nada de POO e ama muito um paradigma vai rebeixar sua postagem e ela vai sumi no limbo do tabnews.

Eu recomendaria um titulo melhor e um texto menos provocativo!

De resto eu concordo que POO é bem ruim em muita coisa e
pior ainda, POO nem padrão tem. Ninguém sabe a definição dela!

2

Eu consigo entender a intenção do Post, o que ele critica, e nesse sentido até poderia concordar com mais pontos, mas ou o título é muito click bait, ou você está batendo num espantalho o artigo todo.

Você falou muito que OOP é lixo, mas não apresentou muitos argumentos sobre os motivos que levam a isso, cada parágrafo apresenta um efeito, sem realmente mostrar que a OOP é a causa dele, outros você simplesmente joga dois pedaços de código, e não faz nenhum juízo de valor (exceto dizer que a versão procedural é mais simples sem elaborar muito também), ou referencia vários links extras sem fazer nenhum comentário por cima, o que não ajuda muito que está lendo o seu artigo a entender o seu ponto, não é nem por uma questão de má vontade, é só que não ajuda muito a criar uma linha de raciocínio se eu tenho que parar para ver uma talk a cada parágrafo do texto para conseguir seguir a sua linha de raciocínio.

Agora pegando ponto-a-ponto do seu texto.

Sobre os motivos para se ignorar a POO, a performance realmente é algo importante, mas assim, claramente não se utiliza OO por conta da performance, se performance fosse o argumento mais importante de todos, a gente não utilizaria outro paradigma que não fosse procedural, ou quem sabe abandonar tudo isso e voltar pro assembly não-estruturado.

Quanto a ter vários livros que tentam corrigir a OO, se algo for tão explorado na academia, e no mercado ao ponto de ser usado em todo lugar religiosamente, até quando não for o ideal, certamente acredito que teríamos livros semelhantes dessa coisa também.

Daquela lista, eu conheço o Elegant Objects, e apesar de eu gostar bastante das opiniões dele, e algumas coisas realmente estarem mais alinhadas com os princípios, claramente o que ele quer é uma forma diferente de FP, e não de OOP, é só acompanhar o próprio blog do autor para entender isso. Alias, esse é um caminho bem parecido com o que o Alan Kay tomou para criar o Smalltalk (já que ele via o Lisp como algo falho), embora claramente as conclusões são diferentes devido aos objetivos serem diferentes.

Livros sobre como lidar com procedural legado realmente existem, um dos melhores livros de PHP que eu já li fala exatamente sobre esse tema, inclusive a solução que ele propõe é a aplicação de um tom mais OO com design patterns (https://www.amazon.com/Modernizing-Legacy-Applications-Paul-Jones/dp/1787124703).

Não se discute muito mais sobre problemas de procedural, porque os problemas já são bem conhecidos, falta de encapsulamento, mecanismos de abstração tendem a ser mais pobres em linguagens que só suportam esse paradigma, estado global, estado mutável sem controle, spagetti code, e etc. Óbvio que com disciplina, e "boas práticas" é possível ser bem sucedido em qualquer paradigma, seja ele a OO, ou o procedural, um dos melhores exemplos disso é o Linux, que é uma comunidade altamente disciplinada.

Sobre a questão da evolução das linguagens, eu não diria que Erlang é uma linguagem lá muito moderna, ela é bem antiga até para falar a verdade, moderno nesse contexto provavelmente seria o Elixir.

Apesar disso, eu tenho uma boa explicação para isso, a FP vem se popularizando muito nos últimos tempos, então o natural é que as linguagens evoluam na direção de ir adotando mais recursos desse paradigma, foi exatamente o que aconteceu com a OO. O motivo é simplesmente que elas evoluem na direção das ferramentas que podem adicionar algo a mais para elas, Java já implementa muitas coisas de OO, não tem muito mais de OO que implementar ali, logo o caminho natural seria ver como ele poderia se beneficiar de outros paradigmas.

Até porque isso reflete até a maneira que nós programamos no dia-a-dia, é muito difícil classificar algo como puramente de um paradigma, você pode ter um código super imperativo, causando efeitos colaterais, dependendo de estado global, e receber uma callback como parâmetro por exemplo. Não é por conta dessa callback que o código virou FP da noite pro dia, ela continua sendo uma solução muito procedural, só que ela incorporou algumas coisas de FP.

Sobre os usos de OO, as consequências estão corretas (existem outras formas de resolver os mesmos problemas), mas isso não ajuda em nada seu argumento, você não disse que o ponto dos defensores era que OO é a única solução para esses problemas, o ponto é que esses seriam campos onde ela seria uma solução efetiva, não é sobre ser melhor ou pior que outras soluções.

Aqui a gente chega no seu primeiro exemplo de código, nesse ponto eu achei o artigo meio desonesto, se você olhar no repositório essa é a versão 1 do código, sendo que elas vão até a versão 11.

O código da versão 11 ainda poderia ser bem mais OO, mas claramente é bem mais OO que o código da versão 1 que você referencia, este por sua vez é bem procedural, não é porque você está usando classes e objetos que você não pode escrever código procedural, inclusive o erro mais comum de quem vai aprender um novo paradigma é forçar o paradigma que domina nesse outro paradigma.

A sua refatoração melhora aquele código justamente porque ele já era muito procedural para começo de conversa, então implementar ele usando técnicas procedurais naturalmente resultaria numa versão melhor daquele código.

Você não pode dizer o mesmo da versão 11. Claro que ainda tem mais arquivos e LoC (Linhas de Código), mas essa não é a única métrica que importa, se não, não existiriam recursos de abstração na maioria das linguagens, e se o único benefício disso (abstração) fosse reúso de código, então a OOP seria o melhor paradigma de todos, já que nada vence herança múltipla + polimorfismo em termos de reúso de código, o problema são as outras coisas que vem disso.

Não vou falar muito sobre legibilidade pois em muitos casos isso tende a ser meio subjetivo, eu por exemplo acho muito mais simples ler um reduce do que um for hoje em dia para qualquer operação em arrays.

Pelo seu código a gente consegue ver uma área onde a OOP realmente se destaca que é o polimorfismo, o seu código teria problemas para evoluir caso novos tipos de código fossem adicionados, e aquele switch só cresceria (e ficaria mais complexo) ao longo do tempo, com OO, isso seria uma aplicação simples do OCP do SOLID.

Sobre padrões de projeto, isso existe em qualquer lugar, são simplesmente as soluções mais comuns que as pessoas tem para qualquer coisa, coleções de padrões existem até para áreas fora da programação como o design.

Claro que padrões de OO não seriam necessários em programação funcional, é outro paradigma completamente diferente. Você poderia dizer o contrário também, você não precisaria de uma State Monad caso tivesse objetos com encapsulamento simples sendo aplicado, você não precisaria de Optional Monad, se soubesse como usar herança simples para implementar um boolean ou uma variação disso para valores nulos, o Alan Kay mesmo já disse que uma das inspirações que ele teve para OO era a capacidade de compor algebras da matemática, que é um conceito muito bem implementado nessas estruturas algebricas.

Mesmo os padrões de OOP, não precisariam de padrões para serem usados com OOP, boa parte deles é simplesmente polimorfismo básico, o template method é só uma forma inteligente de usar herança, o Visitor é só uma aplicação de double dispatch, e assim por diante. Os padrões são úteis pois assim podemos dar nomes para cada tipo de utilização, o que melhora a comunicação.

Ai o último ponto que eu gostaria de comentar seria a sua segunda refatoração.

Para começar que o código original não é a coisa mais OOP do mundo, "a classe Game" aqui teria controle do estado de toda a aplicação, mesmo tendo pelo menos 3 ou 4 objetos que ela dependeria, e que poderiam sim lidar com o seu próprio estado. O padrão Observer não era necessário em Game, pois ele não usou isso em lugar nenhum depois.

Só que o seu código não simplificou em nada o código original, inclusive depender uma função sendUpdate, meio que tem quase o mesmo efeito de implementar um padrão observer é só que é uma solução mais prática e menos robusta.

O seu código piorou o original, ele faz literalmente a mesma coisa que o original, só que ao invés de separar cada ação que vai alterar o estado da aplicação numa função (o que seria um bom senso até em programação procedural), você colapsou todas as funções dentro de um switch gigante, o que só aumenta a complexidade do código ao invés de diminuir.

Juntar tudo em uma única função tem os seus méritos, mas nesse caso nem ajuda muito, pois agora quem for ler o código onde ela foi usada, vai ter que procurar em qual ponto de uma função enorme, que nem é pura, que aquele comando está sendo tratado, ao invés de simplesmente procurar no módulo que lida com ele.

Mesmo que você possa argumentar que existe uma certa equivalencia num switch com actions (similar a um reducer) e um objeto com métodos, os métodos de um objeto são melhores visto que estão menos propensos a erros de digitação.

A OO é boa para várias coisas sim, o encapsulamento permite que você tenha os mesmos benefícios de uma closure em FP, só que numa situação onde existe mais de uma operação que depende dos mesmos dados.

O encapsulamento provido pelo uso de objetos é uma das melhores formas de lidar com dados mutáveis, pois você consegue restringir as formas com que ele pode ser modificado, o que é algo muito útil para softwares empresariais que precisam de políticas fortes que assegurem as regras de negócio da aplicação.

Claro que todo paradigma permite que você reforce regras de negócio, tal como um if e status code no procedural, ou uma result monad em FP, mas só a OO consegue fazer esse tipo de validação a nível de dado para todas as operações que envolvem ele.

A abordagem da FP para esse caso é garantir que os dados são válidos nas bordas, e assumir que eles são válidos no Core, o que é uma ótima ideia também, mas eu não acho que isso diminui os méritos de garantir essa consistência no próprio dado em si.

O polimorfismo é algo que todos podemos concordar que é uma funcionalidade essencial para desenvolvimento de qq software ser saudável. A capacidade de deixar suas opções abertas para o futuro é algo realmente valioso.

Todo paradigma tem alguma forma de suporte a esse conceito, no procedural, apesar de ser o mais limitado nesse tipo de coisa, você pode ter certo grau de polimorfismo usando polimorfismo paramétrico, e ad-hoc, porém isso se limita só aos dados.

Na FP, apesar dos tipos serem os mesmos do procedural, você tem uma vantagem imensa aqui que é a existencia de type classes, e funções como cidadãs de primeira-classe, assim você consegue quase uma equivalencia com o sistema adotado pela OOP.

Na OO, apesar de poder ser argumentado que ela suporte quase todos os tipos, eu gostaria de focar só no princípal que realmente seria algo singular dela, o de subtype.

Pois, por mais que FP seja incrível, o tipo de polimorfismo que ela oferece só resolve metade do Expression problem (https://en.wikipedia.org/wiki/Expression_problem), o modelo de subtyping da OO resolve a outra metade, e esse é um problema justamente pois não tem como resolver os dois lados ao mesmo tempo.

O modelo da FP permite que você adicione mais tipos de dados facilmente a uma função, enquanto a vantagem da OO é o contrário, facilitar a adição de mais funções a um determinado tipo de dado.

Por isso que problemas onde a OO é melhor, geralmente são problemas onde você consegue abstrair uma estrutura hierarquica entre os objetos.

O que nos leva a herança, que apesar de realmente não ser a melhor coisa do mundo, todos conhecermos a famosa ideia de que composição > herança, tem sim uma função vital no dia-a-dia da maioria dos programadores.

Herança, graças as classes abstratas, é uma ótima forma de pegar boas abstrações que emergirem de uma codebase, e centralizar elas num lugar só, de modo a tornar o desenvolvimento mais incremental.

O padrão template method é uma forma legal de ver como isso poderia ser usado no código do dia-a-dia, mas não é nem sobre ele que eu estava falando. Os frameworks que usamos no dia-a-dia são o maior exemplo dos benefícios que essa funcionalidade pode trazer, apesar de realmente não ser uma boa solução em userland, ter ferramentas que se utilizam disso, é um aspecto positivo sobre esse princípio.

E para fechar, eu gostaria de lembrar que OO é sobre as mensagens trocadas pelos objetos, até porque objetos são receptores de mensagens, tipo como uma forma de reducer glorificado, o que fica evidente no sistema de processos baseado em actor model (que é tipo uma versão async da ideia de OO do Alan Kay) do Erlang/Elixir, por isso que o Alan Kay denomina o paradigma como orientação a objetos.

Então onde cada paradigma vai se destacar vai muito de o que você acha que é mais importante, visto que sistemas são sempre a junção de duas coisas: dados e ações.

Se você vê os dados como mais importantes, então a OO realmente não serve para você, um ótimo exemplo disso foi o que vc deu sobre DoD.

Se você vê os comportamentos como mais importantes, então OO vai acabar sendo melhor, um bom exemplo disso é o sistema de recuperação de falhas de sistemas Erlang de telefonia, que tem quase 0 de downtime desde a sua criação.

1

POO e padrões de projetos muitas vezes não são a melhor solução pra um problema, e sim um padrão de leitura de código.

Agora é lixo a partir do momento em que não te serve ou atrapalha, isso eu concordo.

Pra qualquer outro problema resolvido com POO eu discordo, não é lixo não. Muitas vezes mal implementado, mal documentado e entendido sim, se torna lixo.

Ao meu ver não vou lembrar quem foi o criador do POO, mas muitas linguagens como JAVA nem sequer eram somhados na época da "invenção" do POO

Resumindo: É lixo pra uns, luxo pra outros.

faz algum sentido ?

1

Olá, Douglas. Valor é subjetivo. O principal valor da plataforma é reunir conteúdos de "valor", e o conceito de valor neste contexto, depende da avaliação de cada um que ler seu texto.
Arranhando a superfície da questão, Eu diria que os downvotes vieram da personificação do objeto do assunto, o que faz as pessoas levarem uma opinião, que independente da forma como expôs, ou de seu conteúdo, tem como único alvo uma coisa. Que neste caso é a POO.
Neste momento, não tenho bagagem o suficiente pra sequer discutir esse assunto contigo, em primeiro lugar, porque na minha carreira só tive a experiência real com o paradigma procedural e POO, e o segundo é o que tem ocupado a maior parte da minha carreira; em segundo lugar, você trouxe boas referências para a discussão. Seria leviano se Eu não as lesse antes, e trouxesse pra discussão algo de valor pra de fato agregar no que seria uma discussão sobre o que é pior, ou melhor, sem me agarrar à gostos pessoais.
De qualquer forma, sua publicação tem muito valor, e os downvotes neste caso, dizem mais sobre a pessoalidade que o assunto tem, do que o conteúdo em si.
Continue trazendo boas provocações para a plataforma.
Um forte abraço!

1

Cara eu realmente entendo onde você quis chegar com o post. Porém existe 2 pontos importantes a serem destacados.

  1. Você exagerou quanto a "não servir pra nada"
  2. As pessoas não estão entendem suas argumentações.
    Vamos começar pelo 2°, para entender o pq POO não funciona e entender suas argumentações é necessário ter um embasamento muito grande, principalmente sobre outros paradigmas e outras problemáticas sobre o contexto de computação, e até um pouco de histórica. Você deixou alguns links, acho que o pessoal que deu downvote nem abriu...

Sobre o 1° ponto, você exagerou de mais, POO veio para ajudar na manutenção de códigos, para ajudar na abstração da realidade, entre outras coisas... que se você pesquisou como diz, você save bem. Agora não é culpa de POO que os programadores façam gambiarras...

Você falou que Linux não foi escrito em POO, mas isso está mais do que óbvio. O sistemas é baseado em ações, "procedimentos", em "módulos" não faz sentido ser escrito em POO, além do mais ele foi escrito em C, que não tem suporte a orientação a objetos. Pq vc acha que C++ foi criado? Para resolver problemas que C não conseguia, e isso utilizando POO.

Você afirmou também que, se POO fosse tão bom, não teriam criado outras Lang. Mas isso é ser muito mente fechada, parece que você se frustrou com alguma situação e saiu falando o que tinha em mente. GO foi criado para resolver alguns problemas de paralelismo/concorrência em resolver problemas com STRINGS. O MUNDO NAO GIRA EM TORNO DE UM PARADIGMA.

Outros paradigmas vieram depois de POO e cada um pra resolver problemas que POO deixa passar. Java é basicamente POO puro, e é a linguagem mais utilizada para criar ERPs, Grandes sistemas empresariais, que precisam de bastante abstração.

Desenvolvimento de Games, seria basicamente impossível sem POO, jogos como MOBA, onde um champ tem skills parecidas, seria horrível dar manutenção.

Os famosos motores gráficos, não seriam possíveis, não com a "facilidade" de abstração que o POO trás.

Enfim eu poderia dar vários exemplos mas basta pesquisar. No demais, gostei do teu post! Provavelmente está com downvote negativo pq as pessoas não entenderam."Eu acho"

0
1

Poderia elaborar porque a versão dele é "infinitamente mais simples" que a minha?

No post eu não entrei em detalhes do porquê eu acredito que minha versão seja mais fácil de ler e entender. Então, vou explicar aqui. Na minha versão eu removi dois arquivos e um design pattern e no geral simplifiquei a estrutura e reduzi o número de linhas de código. Agora tudo fica centralizado na função updateGame. Além disso, otimizei a lógica de colisão com as frutas, ao invés de iterar por todas as frutas pra verificar a colisão, eu criei um dicionário com as coordenadas x e y da fruta como id. Assim ao invés de ser O(n), fica O(1).

0

Esse -7 no seu post pode indicar duas coisas: ou é um completo absurdo o que foi dito, ou faz todo o sentido e você está enfrentando um establishment na área de software. Milhares de paralelos atualmente no mundo real existem dessas situações, desde vacinas, combustível alternativo, cura do câncer, até sutilezas como malefícios da pasta de dente, BBB (big brother brasil (alô, 1984?)) ou sumiço do botão de deslike do YouTube.

Dito isso, orientação a objetos veio para tentar resolver um problema que existia. As regras da OO parecem simples até você mexer em um legado mal feito usando tudo que OO tem de bom. Vão alegar que é culpa de quem fez que não entendia o conceito ou como aplicar OO. Ora, o avião foi inventado para revolucionar o transporte, em seguida foi usado para guerras e mortes. Bomba atômica o mesmo. Depende da pessoa mas também a invenção em si pode levar muitos para o buraco, e OO não é diferente. Podemos ir além, trabalhar com programação em si só vai destruir tua saúde física e mental, homens biologicamente sempre foram ativos fisicamente, ciência não faz ideia do custo disso na humanidade como um todo. Só são recortes aqui e ali.

Minha conclusão é que precisamos disso, da discordância, debate, livre fluxo de ideias. Pelo menos enquanto dá. Todos aprendem. Se é proibido ou censurado, formalmente ou não, formam-se bolhas e poucos terão acesso ao conhecimento. E já dizia a Bíblia... por falta de conhecimento...

1

Se é um completo absurdo, então eu gostaria de uma boa contra-argumentação. Mas acredito que seja o establishment mesmo. No vídeo do Brian Will - Object-Oriented Programming is Embarrassing: 4 Short Examples tem uns 18 mil dislikes e uns 29 mil likes.
Então, é muito forte na cultura de programação que POO é útil em certos casos, daí surge essa controvérsia.

Orientação a objetos veio para tentar resolver um problema que existia

Mas que problemas? Essa é a grande questão. Em quê a POO é útil?

Minha conclusão é que precisamos disso, da discordância, debate, livre fluxo de ideias.

Concordo. No meu primeiro post eu fiz algumas reflexões sobre minha experiência em programação. Foi mais um desabafo contra conceitos tão difundidos na cultura de programação que são regurgitados de um programador para outro. Poucos param para pensar criticamente sobre esses conceitos e ver se têm algum valor. Obviamente tudo isso é minha opinião baseada na minha experiência e também em outros programadores, com mais experiência que eu, que também compartilham das mesmas ideias.

1

Bom, estou no mercado a cinco anos apenas, não tenho a bagagem necessária para te dar uma boa resposta sobre OO.

O que senti na pele, e sinto até agora, é que tudo é bonito na teoria,até você pegar algo mal projetado em OO. Quando você pega uma herança, polimorfismo, genérics mal projetados e não documentados, se torna um inferno, você vai estar na posição que outro dev estava mas ele sabia, supõe-se, o que estava fazendo. Mesma coisa testes, ninguém fala de manutenção de testes, mas enfim, muitos não estão preparados para essa conversa. Muitos entraram em startup com dinheiro jorrando onde havia 0 accountability do que era feito e ficaram com essa experiência, das mais modernas, e mais fantasiosas. Aquela taxa de juros de 2% no Brasil foi uma benção para uns poucos que vai custar décadas para outros.

0

cara, eu não tive tempo de ler e analizar todos os seus links, mas me explica uma coisa... Como vc trabalharia com desenvolvimento WEB sem utilizar POO?
Não digo q seja impossível, mas seu projeto ficará completamente esquisito e estranho... A estrutura MVC para desenvolver para a WEB é uma das coisas mais fáceis do mundo, mas vc precisa de OO para implementa-la.
Eu queria realmente q vc me esclarecesse isto, pois vi muitos exemplos com C++ e Java, e até um com JS, mas não vi nada com PHP, Python...
Outro ponto também, como hoje em dia vc desenvolveria na área de Machine Learning sem utilizar OO com as bibliotecas como TF, PyTorch... Aí sim vc teria uma perda de performance .