As coisas orientadas a objetos são realmente tão importantes? [fechadas]

8

Durante anos, venho fazendo coisas algorítmicas, escrevendo estruturas de dados escaláveis ​​para pesquisa na Internet, por exemplo, Árvores de Pesquisa Binária Aleatória para Recomendação Automática, BitMaps, Algoritmos baseados em Sabedoria de Multidão usando Gráficos, escrevendo alguns Algoritmos de Aprendizado de Máquina interessantes como Clustering, Detecção de Anomalias, trabalhando em coisas de recuperação de informações e assim por diante

Há uma coisa comum nas coisas que mencionei acima. Todo o material acima, cada um se codificado em uma linguagem como C ++, requer um punhado de classes. Quero dizer, são problemas interessantes, mas não são complexos em termos de material Orientado a Objetos muito carregado. Eu nunca usei Herança, material virtual etc. Embora eu tenha usado muito a Programação Genérica, Modelos e assim por diante.

Eu amo C ++ (- coisas volumosas de OO, como eu gosto do que Joe Armstrong, criador de Erlang diz: No mundo de OO, se você pedir uma banana, você terá uma grande selva junto com um gorila segurando a banana). Eu gosto de codificar em outras linguagens como Java, Python também.

Agora, minha pergunta é: estou gostando do tipo de projeto / algoritmo em que estou trabalhando. Preciso realmente aprender coisas sobre OO; serei um melhor codificador / designer apenas usando coisas como herança, polimorfismo dinâmico (virtuais)? OU posso mudar para o mundo da Programação Funcional (ainda não o fiz até agora), o que me atrai mais, pois posso me concentrar apenas em tarefas / algoritmos e não deixar que o material baseado em OO do Kingdom Of Noun, tem-a, é uma regra mim?

Em suma, as coisas OO podem / podem me ajudar em todos os tipos de projetos / algoritmos que mencionei acima?

EDITAR:

Um link extremamente interessante para adicionar aqui:

http://steve-yegge.blogspot.in/2006/03/execution-in-kingdom-of-nouns.html

Yavar
fonte
25
A orientação a objetos é o paradigma de programação mais utilizado atualmente. Ignora isso a teu risco.
Robert Harvey
5
<sarcasmo> Não, não se preocupe. C deve ser o suficiente para você. </sarcasm>
Otávio Décio
2
Duplicado relacionado / possível: programmers.stackexchange.com/questions/7126/…
Adam Lear
16
Claro que OOP / OOD é superestimado. Este modelo trivial é apenas utilizável para um conjunto restrito de problemas. Mas você não deve ignorá-lo - caso contrário, você acabará usando as ferramentas erradas para aquelas áreas raras e estreitas onde o OOP realmente brilha.
SK-logic
13
Linus Torvalds, é você?
Jesse C. Slicer

Respostas:

9

A programação orientada a objetos é realmente boa para esconder suas complexas coisas matemáticas de fantasia por trás de palavras fáceis de entender e facilitar para que os menos importantes entre vocês usem realmente o que você escreveu. Ele não substitui a programação funcional ... apenas oferece uma maneira muito fácil de mudar implementações ou adicionar comportamento.

No seu exemplo de Árvores de pesquisa binária aleatória acima, e se você recebesse o requisito de que no dia da mentira de abril, o Randomizer fosse substituído por um pedido por distância de três patetas? É realmente útil criar StoogeBinaryTree : RandomBinaryTreee substituir o protected int GetSortOrder (Tree a, Tree b)método. Assim, em 2 de abril, você pode mudar a implementação de volta para o RandomBinaryTreesem precisar alterar nenhum código.

Em um exemplo simples, mostrei a adição de um pouco de comportamento e a alternância de implementação ...

Bryan Boettcher
fonte
14
Isso não é OOP, qualquer sistema decente de módulos faria o mesmo (e, provavelmente, de uma maneira muito mais simples). Veja os módulos SML de 1ª classe, por exemplo.
SK-logic
4
@ SK-logic: E módulos e OOP são significativamente diferentes como, exatamente?
DeadMG
12
@DeadMG, não há BS sobre estados, mensagens e herança na definição de qualquer sistema decente de módulos. Apenas incapsulação, além de muita matemática útil (eu sei que você vai desmaiar neste momento).
SK-logic
2
@ SK-logic: Meus sistemas OOP não usam mensagens, herança ou estado excessivo. Eles encapsulam e, se necessário, também podem ser encapsulados em tempo de execução. Outras pessoas podem fazer as suas de maneira diferente, é claro, mas essa é a escolha delas, e não tem a ver com OOP.
DeadMG 28/02
3
@DeadMG Então, qual é a diferença entre uma linguagem orientada a objetos e uma que não é? De que maneira, por exemplo, Haskell ou Erlang não são orientados a objetos, se tudo o que é necessário para orientação a objetos é um sistema de módulos? Ou você está dizendo que essas são linguagens orientadas a objetos?
sepp2k
8

Se você vai fazer FP ainda com idiomas como Haskell e Erlang que fazem isso bem, não há necessidade de beber o refrigerante OOP. FP É muito poderoso e pode fazer muito, mesmo no mundo real

Dito isto, aprender uma língua OOP não seria uma coisa ruim. Compreender várias maneiras de programar e várias metodologias funcionará a seu favor. Além disso, se você mudar de Haskell ou Erlang para Java, poderá se perguntar como é que alguém pode trabalhar sem um REPL e lambdas.

Zachary K
fonte
E deve-se mencionar que idiomas como o Clojure permitem o POO, mas ainda não o impedem de ser baseado em classe. Ou seja, o Clojure suporta funções polimórficas, interfaces etc. tudo sem a necessidade de criar uma classe (pelo menos não da maneira que C # / Java a define).
Timothy Baldridge
Joe Armstrong argumenta que Erlang é mais OO que C ++ ou Java todos serão, não seja dogmático sobre essas coisas ou você será mordido por ela. Clique no link @ O objeto Erlang está orientado?
Oh, eu não sou, inferno que eu escrevi um livro sobre Erlang ( shop.oreilly.com/product/0636920021452.do ), mas quando as pessoas falam sobre OOP Erlang geralmente não é o que eles querem dizer
Zachary K
7

Parece que você se concentrou apenas em resolver um único problema de cada vez, ou seja, escrever algoritmos. Mas considere como você escreveria um aplicativo GUI, por exemplo, ou algum outro aplicativo enorme que seja possível, requer que você use muito do seu algoritmo. Nesse caso, conhecer o OO será essencial, pois ele ajudará a simplificar seu código para torná-lo mais legível e fácil para outros desenvolvedores usarem, por exemplo, criando uma biblioteca que possa ser carregada como um objeto.

Um dos padrões de design mais importantes da Programação Orientada a Objetos é o Padrão de Estratégia , que no cenário acima também o ajudará bastante. Considere um exemplo em que o usuário apresentaria uma entrada na qual você permitiria que ele executasse um algoritmo. Isso pode ser facilmente uma construção confusa de if / else ou switch / case. Criando uma interface comum para seu algoritmo e usando o Padrão de Estratégia, seu código seria muito mais flexível, legível, mais fácil de estender e, portanto, mais fácil de manter.

kba
fonte
O que você tem a dizer sobre linguagens funcionais que implementam o padrão de estratégia de maneira muito elegante (alguém poderia argumentar, mais ou menos) sem objetos?
Steven Evers
4
-1 Por supor que 1) aplicativos grandes sejam impossíveis sem OOP e 2) que o carregamento da biblioteca esteja de alguma forma vinculado ao OOP. Leia sobre vários despachos (e o problema da expressão) e você começa a perceber que Java / C # / C ++ realmente torna muitas tarefas mais difíceis, colocando restrições desnecessárias no programador.
Timothy Baldridge
1
Diga-me como uma biblioteca que pode ser carregada como um objeto é melhor do que uma que não é carregada como um objeto?
28412 aseq
@SnOrfus Estou defendendo a OO, porque esse é o mundo com o qual estou mais familiarizado. Eu não estou familiarizado com o padrão de estratégia linguagem funcional
kba
2
"padrão de estratégia" Essa é a única coisa que me irrita mais sobre OOP do que qualquer outra coisa. Por que tudo tem que ter um padrão? A única razão pela qual coisas como o padrão de visitantes tiveram que ser inventadas foi que a linguagem usada era tão restrita e complexa que era impossível iterar sobre uma estrutura de dados sem um padrão. Remova a complexidade insana das linguagens OOP modernas e, de repente, crie padrões como funções simples. Os padrões são simplesmente uma maneira de fazer som OOP como ele tem uma idéia do que o seu fazendo </ discurso>
Timothy Baldridge
6

A abordagem orientada a objetos se tornou bem-sucedida por causa de um aspecto crucial: permite lidar com sistemas de complexidade essencial significativa sem introduzir muita complexidade acidental . Isso pode ser quase ignorado quando você trabalha em sistemas domésticos, mas se torna muito importante quando você cria sistemas em grande escala.

Os elementos-chave da abordagem orientada a objetos podem ser explicados a um programador com ampla exposição à programação procedural em questão de dias, o que ajudou a técnica a ganhar popularidade rapidamente (isso não significa que você pode se tornar um especialista em um alguns dias: é semelhante a aprender xadrez - você pode aprender a mover suas peças em menos de dez minutos, mas leva anos para dominar o jogo).

Técnicas de programação funcional estão ganhando mais importância com a introdução do suporte a idiomas nas linguagens convencionais (lambdas e delegados anônimos de C #, lambdas de C ++ e até classes anônimas de Java, até certo ponto). É muito útil entender essas técnicas, mas elas são projetadas para resolver problemas mais localizados na escala tática . As técnicas orientadas a objetos, por outro lado, permanecem relevantes na escala estratégica , especialmente no contexto de equipes maiores.

dasblinkenlight
fonte
3
Embora eu aprecie o sentimento expresso em relação à complexidade, infelizmente, na prática, o oposto é verdadeiro. As linguagens OO têm um talento especial para introduzir inchaço e complexidade desnecessários. Isso geralmente não é culpa da linguagem. Mas acredito que, se uma técnica é propensa a fazer com que muitas pessoas a usem incorretamente, pode ser um pouco falha. Não importa o quanto isso pareça legal em teoria.
Aseq)
1
+1 para dasblinkenlight e não concordo com aseq. Em particular, acho que o OO mapeia de perto o necessário para fazer qualquer GUI orientada a eventos e, como há muita atividade na interface do usuário, há muita atividade nas estruturas OO. Faça uma interface do usuário sem uma estrutura OO e você acabará criando algo muito mais confuso (consulte X11 Xt); essa complexidade essencial ainda existe, sem a estrutura que se projeta de maneiras horríveis. Use a ferramenta certa para o trabalho. Quando um profissional não qualificado usa a ferramenta errada, você culpa o idioma ou o profissional?
Liudvikas Bukys
@aseq "Mas acredito que, se uma técnica é propensa a fazer com que tantas pessoas a usem incorretamente, pode ser um pouco falha." Olhar para os números brutos é enganoso, porque diferentes tecnologias atraem diferentes números de praticantes. As porcentagens seriam um pouco mais significativas, mas não estão prontamente disponíveis. Além disso, as barreiras à entrada e a estrutura de incentivos não tecnológicos impedem profissionais de diferentes graus de qualidade ; portanto, mesmo porcentagens podem não fornecer uma imagem completa.
dasblinkenlight
1
Não vejo como a programação funcional não é "estratégica". É melhor que OOP para escalas maiores, pois reduz o acoplamento e a complexidade e permite trabalhar em um nível mais alto de abstração. Além disso, existem algumas técnicas muito boas para criar interfaces de usuário de uma maneira puramente funcional: confira "programação reativa funcional".
Tikhon Jelvis
4

Faça a programação funcional, será uma experiência muito boa para você, mesmo se você decidir não continuar. Como você pode ler algumas das respostas aqui, muitas pessoas nem sabem o que é.

Conceitos de linguagens funcionais, por exemplo, avaliação lenta e transparência referencial, são uma coisa muito muito boa para aprender. Especialmente se você gosta de recursão.

por exemplo:

lenth :: [a] -> Integer
length (x:xs) = 1+length(xs)
length [] = 0

é uma função haskell muito simples que se repete através de uma lista e calcula o comprimento. Se você estiver interessado em números maiores que longos e quiser usar Listas infinitas e outras coisas sofisticadas, experimente a programação funcional.

Baarn
fonte
2
É também uma maneira estúpida (percorrer manualmente em vez de usar abstrações pré-construídas e ineficazes) para implementar length. Uma maneira diferente (mais eficaz e mais próxima de como os programas de FP não triviais são realmente escritos) pode estar dando algumas dobras no valor inicial 0e na função de etapa acc -> acc + 1. Alternativamente, sum . map (const 1)lê bem.
1
@ Giorgio Não, a função não é recursiva da cauda. E mesmo que fosse, em idiomas como Haskell, que estão tangivelmente relacionados à eficiência e ao uso da pilha (é preciso evitar a criação de grandes thunks; nem isso nem um lengthconstruído sobre os folds não-estritos fazem isso).
2
@ Jordan: Exceto que em Haskell, os valores não podem ser modificados e nem todas as listas têm um comprimento (finito).
31412 Jon Purdy
3
@ WalterMaier-Murdnelch Sim, a lista terá que ser percorrida eventualmente e é preciso entender o que acontece sob o capô. Mas isso não torna as abstrações inúteis, muito pelo contrário. Eu poderia escrever consultas SQL (acima do Yesod persistent), tratamento de erros (acima Maybe/ Either), malabarismo de estado (acima State), travessias de árvore (acima Map/ Set), etc., mas descrever minha intenção em termos de funcionalidade de nível superior é melhor em praticamente todos os aspectos e, portanto, também o que o FP faz na prática.
1
@Giorgio Em linguagens estritas, que ainda são a norma, é - embora também dependa do compilador que cuida dessa otimização (Python, apesar de alguns mitos urbanos, não é uma linguagem funcional e não otimiza chamadas de cauda - Lua OTOH faz). Porém, assim que você não é rigoroso (exemplo mais importante: Haskell), as regras mudam. Você pode ser recursivo de cauda e ainda obter um estouro de pilha porque criou uma enorme conversão (um milhão de adições de números inteiros empilhados adiadas devido à preguiça), ou (sem cauda) recuar descontroladamente e se dar bem. Então, eu não aceitaria essa regra como evangelho.
2

Como outros já disseram, a orientação a objetos é o paradigma dominante na indústria. Você disse que trabalhou principalmente com programas que podem ser abordados por várias classes, mas em um aplicativo industrial existem centenas ou milhares de casos de uso que precisam ser abordados e a orientação a objetos se mostrou muito confiável. e uma maneira amplamente compreensível de estruturar essas grandes bases de código.

Você fala sobre programação funcional, que é um sólido candidato ao The Next Big Paradigm, mas o FP ainda não é familiar no setor. Especialmente como você é um programador de C ++, você deve saber que o setor pode ser conservador e o mundo de C / C ++, com ênfase no desempenho, é um lugar onde a natureza imperativa do hardware é vista como uma consideração muito real. Em geral, programadores de sistemas embarcados são extremamente céticos em relação à FP, na minha experiência.

Mesmo se FP faz se tornar um paradigma mais dominante na indústria, é certamente o caso que ele vai ter sucesso na forma de linguagens híbridas de objetos funcionais como F # e Scala e não na forma de "puros" línguas FP, como Haskell.

Tudo isso é para dizer que sim, as "coisas" orientadas a objetos são importantes para as bases de código profissionais e sua carreira.

Larry OBrien
fonte
2

OO ganhou força porque foi uma grande melhoria para lidar com a complexidade, como antes também era a programação estruturada / processual.

Os benefícios do uso de OO aumentam à medida que o tamanho do projeto aumenta. Para um programa 1KLOC, não importa muito qual paradigma você use, todos eles funcionarão bem. Porém, para um programa de 200KLOC +, simplesmente não existe concorrência viável para OO. Isso não significa que você não pode escrever um programa de 200KLOC em C, apenas que precisará ser muito mais disciplinado para evitar acabar com uma bagunça que ninguém (nem você) pode entender. Isso não significa que o OO evitará essa bagunça, apenas facilitará sua vida para evitá-la.

A programação funcional é um paradigma que se desvia um pouco do padrão anterior, porque não veio para ajudar a lidar com ainda mais complexidade do que o OO, mas para resolver um tipo diferente de problemas: a programação paralela. Essa foi a primeira vez, também, que um paradigma de programação tentou fazê-lo: todos os mecanismos que existiam anteriormente no OO e / ou SP / PP não faziam parte do paradigma, mas apenas entidades do SO (threads, mutexes etc.) encapsulado de acordo com as regras do paradigma.

Nesse sentido, o FP é muito mais natural que os outros, mas isso tem o custo de reverter a maneira como geralmente pensamos sobre os problemas. E devido a isso, ele tem uma capacidade limitada de lidar com a mesma complexidade na mesma escala que o OO.

Meu palpite é que isso limitará a adoção do PF em um futuro próximo a sistemas muito especializados, em geral não muito grandes, ou seções especializadas de sistemas maiores. E o resto ainda será feito usando OO. Qual das pessoas que você planeja desenvolver (ou aprender sobre o desenvolvimento) determinará qual deve ser seu foco de aprendizado, a IMO.

Fabio Ceconello
fonte
1

Embora eu tenha usado muito a Programação Genérica, Modelos e assim por diante.

Indiscutivelmente, os modelos são simplesmente uma forma diferente de POO. Funções virtuais e herança explícita têm uma intercambiabilidade binária em tempo de execução de caso de uso específica. Modelos são intercambiáveis ​​em tempo de compilação. No entanto, no nível mais básico, eles oferecem a mesma abstração de recurso sobre qualquer tipo que ofereça a interface correta. O uso excessivo da herança em tempo de execução é um cheiro significativo ao código e, nesse caso, eu concordo com você - simplesmente não é necessário por grande parte do tempo.

template<typename T> void func(T t) { t(5); }
void func(std::function<void(int)> t) { t(5); }

Esses dois trechos são efetivamente idênticos, mesmo que um use modelos exclusivamente e o outro use herança e classes em tempo de execução como implementação. Ambos abstraem a função que você está chamando. Esta é trivialmente óbvio quando você substituir Tpara std::function<void(int)>, por exemplo. A única diferença é a hora em que essa abstração é feita. A versão do modelo é excelente para funções e std::functiongeralmente é melhor como variáveis ​​de membro. Você não precisa criar uma nova classe sempre que desejar um novo retorno de chamada.

OOP não é particularmente adequado para algoritmos. Destina-se a construções de larga escala, dividindo as partes do programa. Se você estiver escrevendo um algoritmo específico operando em dados específicos, é improvável que você precise de classes.

É fácil, e é ótimo, compor algoritmos de funções. No entanto, assim que você ultrapassa isso, as classes emergem como o método dominante.

DeadMG
fonte
9
Uau! Modelos são uma "forma de POO"? Você fez o meu dia, cara!
SK-logic
4
Os modelos são para programação genérica. Eu não acho certo dizer que os modelos são simplesmente uma forma diferente de OOP. Espero que Alex Stepanov não esteja lendo isso :) #
454 Yavar
Como demonstrei, as duas funções são efetivamente equivalentes e têm a mesma abstração. Simplesmente ocorre em um momento diferente.
28412 DeadMG
4
A comunidade C ++ hoje usa a meta-programação de modelos para as coisas feitas anteriormente de uma maneira mais OOP. No entanto, eu não chamaria isso de "uma forma diferente de POO". Especialmente no exemplo acima, eu chamaria "uma maneira C ++ de usar objetos functor como uma forma especial de programação funcional", o que não é uma solução típica de POO.
Doc Brown
4
Eles se sobrepõem em alguns recursos, certo. Isso é porque ambos são úteis, então existem inevitavelmente algumas coisas que ambos fazem bem. Mas isso não mostra que eles são isomórficos o tempo todo e não mostra que são igualmente úteis (por exemplo, sucintos e eficazes) para todos os problemas. Uma lista vinculada puramente funcional também compartilha alguns recursos com matrizes dinâmicas e com alocação excessiva - ambas são coleção ordenada, podem ser criadas incrementalmente com complexidade razoável, suportam bem o uso de pilha (push / pop / peek), etc. mas diferem amplamente, conceitualmente e em inúmeras aplicações reais.
1

Sim, é importante, por esse único motivo: entender o POO faz de você um programador melhor. Como regra geral: entender sempre faz de você um programador melhor.

Deve-se notar que nem is-a, nem classes e muito menos herança têm algo a ver com OOP. O que realmente é OOP é dissociar por meio de indireção, conforme formulado pelo princípio de inversão de dependência . Pode-se argumentar que esse também é um aspecto importante do PF. Se estudar tanto OOP quanto FP, você ficará cada vez mais ciente de que eles são realmente dois lados de um continuum. Quanto mais amplo e profundo o seu entendimento, melhor você se tornará.

Para entender o POO, tente Io e talvez Smalltalk e Ruby.

back2dos
fonte
0

No mundo do desenvolvimento, linguagens são ferramentas, paradigmas de programação são ferramentas e bibliotecas são ferramentas. Quanto mais ferramentas você tiver, melhor poderá selecionar a ferramenta certa para o trabalho. Então, isso seria um argumento para você aprender OO, AOP e programação funcional - conforme o tempo permitir.

O mundo do desenvolvimento continua crescendo cada vez mais (em termos de idiomas, estruturas etc.), então você não pode esperar aprender tudo. No entanto, o objetivo de todas essas inovações é ajudar os desenvolvedores a se tornarem mais produtivos (velocidade de desenvolvimento e reutilização) e tornar o código mais sustentável (facilidade de entendimento, facilidade de estender e modificar).

A melhor coisa que você pode fazer é realizar um aprendizado direcionado e contínuo, na esperança de que algo novo que você acabou de aprender o ajude a concluir algo melhor e mais rápido de uma maneira que você nunca esperava.

Sam Goldberg
fonte
-1

Eu tenho lido o livro de Steve Jobs e há uma história sobre como Steve viu o SmallTalk nos laboratórios Xerox PARC. Essa foi uma das primeiras línguas OO. Sem OO, seria horrível desenvolver algo como uma Interface Gráfica de Usuário (GUI). Com toda a entrada assíncrona e poder saltar de uma tarefa para outra enquanto trabalha com um "Objeto" ou outro.

Então, enquanto você pode fazer muito com uma linguagem funcional e definitivamente possui seus casos de uso. Quando você começa a lidar com sistemas mais complexos que interagem mais com problemas do mundo real, você encontra OO como um design superior.

Bill Leeper
fonte
a primeira estrutura da interface gráfica do usuário do Macintosh (Toolbox) era um pântano hediondo de C que faz o Win32 parecer saudável em comparação. OO não entrou no mundo Mac até a mudança para o OSX! Essa é uma analogia terrível e historicamente enganosa, na melhor das hipóteses. O Wings3D foi escrito em Erlang e possui uma interface gráfica muito rica e é o caso de uso "mundo real", complexo e prático possível.
Reforça como a programação funcional não se encaixa bem, não é. (Ainda não terminei o livro, interessante como eles não escolheram usar um dos muitos avanços que a equipe da Xerox estava fazendo, parecia que a equipe da Xerox estava muito à frente do seu tempo)
Bill Leeper
Você percebe que Erlang é uma linguagem funcional e o Wings3D é uma GUI muito avançada e complicada, que contradiz sua afirmação de que a programação funcional não é prática e o OO é melhor, o que não é, a menos que você não compreenda a teoria funcional.