Pergunta

Pelo que posso dizer, apesar dos incontáveis ​​milhões ou bilhões gastos em educação, linguagens e ferramentas de OOP, a OOP 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 entendem princípios como LSP);parece haver pouca uniformidade ou consistência nas abordagens que as pessoas adotam para modelar domínios de problemas.Com muita frequência, a classe é usada simplesmente por seu açúcar sintático;ele coloca as funções de um tipo de registro em seu próprio namespace.

Escrevi uma grande quantidade de código para uma ampla variedade de aplicativos.Embora tenha havido lugares onde a verdadeira subtipagem substituível desempenhou um papel valioso na aplicação, estes foram bastante excepcionais.Em geral, embora se fale muito da boca para fora sobre "reutilização", a realidade é que, a menos que um trecho de código exatamente o que você deseja fazer, há muito pouca "reutilização" econômica.É extremamente difícil projetar classes para serem extensíveis no caminho certo, e assim 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 ideia implícita em OO - de que podemos modelar coisas com alguma taxonomia de classe - me parece fundamentalmente falha (posso sentar em uma mesa, em um toco de árvore, no capô de um carro , o colo de alguém - mas nenhum desses é - uma cadeira).Mesmo se passarmos para domínios mais abstratos, a modelagem OO é muitas vezes 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 da OOP e por que todo o tempo e dinheiro não conseguiram melhorar o software?

Foi útil?

Solução

Não há nenhuma evidência empírica que sugira que a orientação a objetos seja uma forma mais natural de as pessoas pensarem sobre o mundo.Existem alguns trabalhos no campo da psicologia da programação que mostram que OO não é mais adequado do que outras abordagens.

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

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

Extraído de "Sobre a usabilidade de representações OO" de Communications of the ACM Out.2000.Os artigos comparam principalmente OO com a abordagem orientada a processos.Há muitos estudos sobre como as pessoas que trabalham com o método OO “pensam” (Int.J.de Estudos Humano-Computador 2001, edição 54, ou Interação Humano-Computador 1995, vol.10 tem todo um tema sobre 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.

Outras dicas

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

Embora isto seja verdade e tenha sido observado por outras pessoas (veja Stepanov, inventor do STL), o resto é um disparate.OOP pode ter falhas e certamente não é uma solução mágica, mas torna os aplicativos de grande escala muito mais simples porque é uma ótima maneira de reduzir dependências.Claro, isso só é verdade para um “bom” design OOP.Um design desleixado não trará nenhuma vantagem.Mas um design bom e desacoplado pode ser modelado muito bem usando POO e não bem usando outras técnicas.

Existem modelos muito melhores e mais universais (Modelo de tipo de Haskell vem à mente), mas estes também são muitas vezes mais complicados e/ou difíceis de implementar de forma eficiente.OOP é uma boa troca entre extremos.

OOP não se trata de criar classes reutilizáveis, mas sim de criar classes utilizáveis.

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

Sim, acho que isso também é muito comum.Isto não é Programação Orientada a Objetos.É programação baseada em objetos e programação centrada em dados.Em meus 10 anos de trabalho com linguagens OO, vejo pessoas principalmente fazendo Programação Baseada em Objetos.OBP quebra muito rapidamente, IMHO, já que você está essencialmente 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 bem feito é uma coisa linda.Facilita a solução de problemas muito difíceis e, para os não iniciados (sem tentar parecer pomposo), pode quase parecer mágica.Dito isto, OOP é apenas uma ferramenta na caixa de ferramentas das metodologias de programação.Não é a metodologia definitiva.Acontece que se adapta bem a aplicações de grandes empresas.

A maioria dos desenvolvedores que trabalham em linguagens OOP estão utilizando exemplos de OOP feitos corretamente nas estruturas e tipos que 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 linguagens, a pilha ASP.NET, a pilha JSP etc...Todas essas coisas dependem fortemente de OOP em suas bases de código.

A reutilização não deveria ser um objetivo da OOP - ou de qualquer outro paradigma nesse sentido.

A reutilização é um efeito colateral de um bom design e um nível adequado de abstração.O código consegue a reutilização fazendo algo útil, mas não ao ponto de 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.

A ideia de OO como uma nova maneira de reutilizar por meio de herança é fundamentalmente falha.Como você observa, as violações do LSP são abundantes.Em vez disso, OO é propriamente pensado como um método de gerenciamento da 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.

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

Quase religioso, mas eu diria que você está pintando um quadro excessivamente sombrio do estado da OOP moderna.Eu diria que na verdade tem reduziu custos, tornou gerenciáveis ​​grandes projetos de software e assim por diante.Isso não significa que o problema fundamental da confusão de software foi resolvido e não significa que o desenvolvedor médio seja um especialista em OOP.Mas a modularização da função em componentes de objetos certamente reduziu a quantidade de código espaguete existente no mundo.

Posso pensar em dezenas de bibliotecas que são lindamente reutilizáveis ​​e que economizaram tempo e dinheiro que nunca poderão ser calculados.

Mas na medida em que a POO tem sido uma perda de tempo, eu diria que é por causa da falta de treinamento do programador, agravada pela curva de aprendizado íngreme de aprender um mapeamento de POO específico de uma linguagem.Algumas pessoas "obtêm" OOP e outras nunca.

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

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

Veja, este é o problema com cada discussão envolvendo OOP ou técnicas alternativas:ninguém tem clareza sobre a definição, todos estão falando de outra coisa e, portanto, nenhum consenso pode ser alcançado.Parece uma perda de tempo para mim.

É um paradigma de programação.Projetado para tornar mais fácil para nós, meros mortais, dividir um problema em partes menores e viáveis.

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

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

Em relação à programação processual direta, o primeiro princípio fundamental da OOP é a noção de ocultação e encapsulamento de informações.Essa ideia leva à noção de aula que separa a interface da implementação.Estes são conceitos extremamente importantes e a base para implementar um quadro para pensar sobre a concepção de programas de uma forma diferente e melhor (eu penso).Você realmente não pode argumentar contra essas propriedades - não há nenhuma compensação e é sempre uma maneira mais limpa de modular as coisas.

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

Relativo à reutilização.Concordo que a reutilização é vendida em excesso para OOP.É um possível efeito colateral de objetos bem definidos, normalmente 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 tanto autodocumentadas.

O problema com OOP é que ele foi vendido em excesso.

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

Depois, alguns consultores de gestão agarraram-se a ele e venderam-no como o messias do software, e, como um lemingue, a academia e a indústria caíram atrás dele.

Agora eles estão cambaleando como se fossem lemingues, depois que outras boas ideias foram vendidas em excesso, como a programação funcional.

Então, o que eu faria de diferente?Plenty, e eu escrevi um livro sobre isso.(Está esgotado - não recebo um centavo, mas você ainda pode conseguir cópias.)Amazonas

Minha resposta construtiva é olhar para a programação não como uma forma de modelar coisas no mundo real, mas como uma forma de codificar requisitos.

Isso é muito diferente e se baseia na teoria da informação (em um nível que qualquer pessoa pode compreender).Diz que a programação pode ser vista como um processo de definição de linguagens, e a habilidade em fazê-lo é essencial para uma boa programação.

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

Procura revigorar a ideia de que o caminho a seguir reside na inventividade e que mesmo as ideias bem aceites devem ser questionadas.

HANDLEs (e o resto do WinAPI) é OOP!

Eles são, entretanto?Eles não são herdáveis, certamente não são substituíveis, carecem de classes bem definidas...Eu acho que eles ficam muito aquém de "OOP".

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

Os identificadores podem não ser herdáveis, mas há final em Java.Aula não lhes falta, eles são um espaço reservado para a classe:É isso que a palavra “alça” significa.Observando arquiteturas como MFC ou .NET WinForms, fica imediatamente óbvio que, exceto pela sintaxe, nada é diferente do WinAPI.

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

OOP se presta bem à programação de estruturas internas de computador, como "widgets" de 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 trabalhamos no mundo dos negócios, onde trabalhamos com conceitos de negócios como Fatura, Funcionário, Trabalho, Pedido.Esses não prestam-se tão bem à POO porque os "objetos" são mais nebulosos, sujeitos a alterações de acordo com a reengenharia de negócios e assim por diante.

O pior caso é onde o OO é aplicado com entusiasmo aos bancos de dados, incluindo as flagrantes "melhorias" de OO nos bancos de dados SQL - que são justamente ignorados, exceto por novatos em bancos de dados que assumem que devem ser a maneira correta de fazer as coisas porque são mais recentes.

Na minha experiência de revisão de código e design de projetos pelos quais passei, o valor da OOP não é totalmente percebido porque muitos desenvolvedores não conceituou adequadamente o modelo orientado a objetos em suas mentes.Portanto, eles não programam com design OO, muitas vezes continuando a escrever códigos procedurais de cima para baixo, tornando as classes bastante interessantes. plano projeto.(se é que você pode chamar isso de "design" em primeiro lugar)

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

No entanto, quando um bom design OO está presente, é uma grande alegria ler o código e ver o código se encaixar naturalmente em componentes/classes intuitivos.Sempre considerei a arquitetura e o design de sistemas como projetar os vários departamentos e cargos da equipe em uma empresa - todos estão lá para realizar uma determinada parte do trabalho no grande esquema das coisas, emitindo a sinergia necessária para impulsionar a organização/sistema.

Isso, claro, é bastante cru infelizmente.Assim como a proporção entre objetos físicos lindamente projetados e objetos horrivelmente projetados no mundo, o mesmo pode ser dito sobre engenharia e design de software.Ter boas ferramentas à disposição não confere necessariamente boas práticas e resultados.

Talvez um gorro, um colo ou uma árvore não sejam uma cadeira, mas todos são instáveis.

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

Você faz?

Quais são os métodos de uma fatura?Oh espere.Ele não pode pagar sozinho, não pode enviar sozinho, não pode comparar-se 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 preferir), não um objeto.

Da mesma forma as outras coisas que você mencionou.

Só porque algo é real não significa que seja um objeto no sentido OO da palavra.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.

Tenho escrito código OO nos últimos 9 anos ou mais.Além de usar mensagens, é difícil imaginar outra abordagem.O principal benefício que vejo está totalmente alinhado com o que 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 fracamente acoplado e altamente coeso com uma clara separação de interesses).

Acho que o OO falha quando as pessoas criam hierarquias de classes profundamente aninhadas.Isso pode levar à complexidade.No entanto, fatorar a funcionalidade comum em uma classe base e reutilizá-la em outras classes descendentes é algo profundamente elegante, IMHO!

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

Dito isto, OO é uma maneira diferente de organizar as coisas, anexando código processual aos dados em vez de fazer com que o código processual opere nos dados.Isto deveria ser pelo menos uma pequena vitória por si só, uma vez que há casos em que a abordagem OO é mais natural.Afinal, nada impede 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 OO faz muito bem:permite que o código antigo chame o novo código automaticamente, sem alterações.Se eu tiver um código que gerencia as coisas processualmente e adicionar um novo tipo de coisa semelhante, mas não idêntica a anterior, terei que alterar o código processual.Em um sistema OO, eu herdo a funcionalidade, mudo o que gosto e o novo código é usado automaticamente devido ao polimorfismo.Isto aumenta a localidade das mudanças, e isso é uma coisa boa.

A desvantagem é que um bom OO não é gratuito:requer tempo e esforço para aprendê-lo corretamente.Por ser uma palavra da moda, há muitas pessoas e produtos que fazem isso mal, apenas por fazer.Não é mais fácil projetar uma boa interface de classe do que uma boa API processual, e há todo tipo de erros fáceis de cometer (como hierarquias profundas de classes).

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

@Sean

No entanto, fatorar a funcionalidade comum em uma classe base e reutilizá-la em outras classes descendentes é algo profundamente elegante, IMHO!

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

@Konrad

OOP pode ter falhas e certamente não é uma solução mágica, mas torna os aplicativos de grande escala muito mais simples porque é uma ótima maneira de reduzir dependências

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

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 um monte de funções simples (ou "flutuantes") diferentes para fazer a mesma coisa com os mesmos dados.Existe um certo "fluxo" natural para coisas com boa OOP que 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 ela mesma pode executar - a instância do objeto pode existir apenas para executar funções nos dados sem a necessidade de saber que tipo de dados realmente existe.A função "invoice.toJson()" pode ser chamada com sucesso sem a necessidade de saber que tipo de dado é "invoice" - o resultado será Json, não importa se vem de um banco de dados, XML, CSV ou até mesmo outro objeto JSON .Com funções procedurais, de repente você precisa saber mais sobre seus dados e acaba com funções como "xmlToJson()", "csvToJson()", "dbToJson()", etc.Eventualmente, torna-se uma bagunça completa e uma ENORME dor de cabeça se você alterar o tipo de dados subjacente.

O objetivo da 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 primordial da OOP é facilitar a manutenção e alterações futuras do código.Mas, além disso, pode realmente simplificar muito as coisas quando feito corretamente de uma forma 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 de qualquer maneira.OOP é apenas uma ferramenta que torna meu trabalho mais fácil e rápido - farei isso a qualquer dia.

@CodingTheWheel

Mas na medida em que a POO tem sido uma perda de tempo, eu diria que é por causa da falta de treinamento do programador, agravada pela curva de aprendizado íngreme de aprender um mapeamento de POO específico de uma linguagem.Algumas pessoas "obtêm" OOP e outras nunca.

Não sei se isso é realmente surpreendente.Eu acho que abordagens tecnicamente sólidas (LSP sendo a coisa óbvia) tornam difícil de usar, mas se não usarmos essas abordagens, o código será frágil e inextensível de qualquer maneira (porque não podemos mais raciocinar sobre isso).E acho que os resultados contra-intuitivos aos quais a POO nos leva não surpreendem que as pessoas não entendam.

Mais significativamente, uma vez que o software já é fundamentalmente demasiado difícil para seres humanos normais escreverem de forma fiável e precisa, deveríamos realmente exaltar uma técnica que é consistentemente mal ensinada e que parece difícil de aprender?Se os benefícios fossem claros, talvez valesse a pena perseverar apesar da dificuldade, mas não parece ser o caso.

@Jeff

Em relação à programação processual 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 bem conhecidos - inferno, os HANDLEs vivem do outro lado da barreira do modo kernel, e isso realmente não acontece muito mais encapsulado que isso) também é encontrado no código processual;Estou lutando para ver como isso é algo específico do OOP.

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

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

Ainda acredito que OO está para não-OO assim como programar com funções está para programar tudo in-line.

(E eu deveria saber, já que comecei com o GWBasic.) Quando você refatora o código para usar funções, variable2654 torna-se variable3 do método em que você está.Ou, melhor ainda, tem um nome que você possa entender, e se a função for curta, é chamado value e isso é suficiente para uma compreensão completa.

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

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



Não acho que OO seja uma metáfora natural.

Também não acho que a linguagem seja uma metáfora natural, nem acho que os "cheiros" de Fowler são melhores do que dizer "esse código tem um gosto ruim". Dito isto, acho que oo não é sobre metáforas naturais e pessoas que pensam objetos simplesmente aparecem em você estão basicamente perdendo o foco. Você define o universo objeto, e melhores universos de objetos resultam em código mais curto, mais fácil de entender, que funciona melhor ou todos esses (e alguns critérios que estou esquecendo).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ê cria um sistema de reservas de companhias aéreas, o que você chama de reserva pode não corresponder de forma alguma a uma reserva legal/comercial.



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

Acho que a maioria das pessoas exagera com aquela coisa de “quando você tem um martelo, são todos pregos”.Acho que o outro lado da moeda/espelho é igualmente verdadeiro:quando você tem um gadget como polimorfismo/herança, você começa a encontrar usos onde ele se encaixa como uma luva/meia/lente de contato.As ferramentas de OO são muito poderosas.A herança única é, penso eu, absolutamente necessária para que as pessoas não se deixem levar, a minha apesar do software de herança múltipla.



Qual é o objetivo do OOP?

Acho que é uma ótima maneira de lidar com uma base de código absolutamente enorme.Acho que permite organizar e reorganizar seu código e fornece uma linguagem para fazer isso (além da linguagem de programação em que você está trabalhando) e modulariza o código de uma forma bastante natural e fácil de entender.

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

Isso ocorre porque é um processo revelador 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 é você parar de usar herança para classes que você não controla e preferir o Fachada padrão em vez disso.



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

Eu queria mencionar que você está certo.A reutilização é um sonho, em sua maior parte.Aqui está uma citação de Anders Hejilsberg sobre esse assunto (brilhante) daqui:

Se você pedir aos programadores iniciantes que escrevam um controle de calendário, eles geralmente pensam consigo mesmos: "Oh, eu vou escrever o melhor controle de calendário do mundo!Vai ser polimórfico em relação ao tipo de calendário.Ele terá exibores, e mungers, e isso, isso e o outro. "Eles precisam enviar um aplicativo de calendário em dois meses.Eles colocam toda essa infraestrutura no controle e depois passam dois dias escrevendo um aplicativo de calendário ruim sobre ele.Eles vão pensar: "Na próxima versão do aplicativo, eu farei muito mais".

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

Você já criou uma janela usando WinAPI?

Mais vezes do que gostaria de lembrar.

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 adota a nomenclatura do SmallTalk OOP, chamando os métodos de “mensagens” (Window Messages).

Então você também saberá que ele não envia mensagens por conta própria, o que é um grande vazio.Ele também tem subclasses ruins.

Os identificadores podem não ser herdáveis, mas há final em Java.Não falta aula, eles são um espaço reservado para a aula:É isso que a palavra “alça” significa.Observando arquiteturas como MFC ou .NET WinForms, fica imediatamente óbvio que, exceto pela sintaxe, nada é diferente do WinAPI.

Eles não são herdáveis ​​nem na interface nem na implementação, são minimamente substituíveis e não são substancialmente diferentes do que os codificadores procedurais têm feito desde sempre.

É realmente isso?As melhores partes do OOP são apenas...código processual tradicional? Isso é o grande problema?

concordo plenamente com InSciTek Jeffresposta, adicionarei apenas os seguintes refinamentos:

  • Ocultação e encapsulamento de informações:Crítico para qualquer código sustentável.Pode ser feito com cuidado em qualquer linguagem de programação, não requer recursos OO, mas isso tornará seu código um pouco parecido com OO.
  • Herança:Existe um domínio de aplicação importante para o qual todos aqueles OO é um tipo de e contém-a relacionamentos são perfeitos:Interfaces gráficas de usuário.Se você tentar construir GUIs sem suporte à linguagem OO, acabará construindo recursos semelhantes ao OO de qualquer maneira, e será mais difícil e mais sujeito a erros sem suporte à linguagem.Glade (recentemente) e X11 Xt (historicamente), por exemplo.

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

Acredito que a qualidade mais benéfica da OOP é a ocultação/gerenciamento de 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ê deva.No entanto, se isso tornar seu código mais organizado/fácil de ler, você definitivamente deveria.

Um ótimo exemplo prático onde OOP é muito útil é com uma classe "produto" e objetos que utilizo em nosso site.Como cada página é um produto e cada produto tem referências a outros produtos, pode ficar muito confuso saber a qual produto os dados que você possui se referem.Esta variável "strURL" é o link para a página atual, ou para a página inicial, ou para a página de estatísticas?Claro que você poderia criar todos os tipos de variáveis ​​diferentes que se referissem à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 ocorreria.Além disso, se eu tivesse que passar as variáveis ​​corretas para essas funções, voltaria 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 bonitos, limpos e fáceis de entender.

No entanto.O grande problema com OOP é quando alguém acredita que TUDO deveria ser OOP.Isso cria muitos problemas.Tenho 88 tabelas em meu banco de dados.Tenho apenas cerca de 6 aulas, e talvez devesse ter cerca de 10.Definitivamente não preciso de 88 aulas.Na maioria das vezes, acessar diretamente essas tabelas é perfeitamente compreensível nas circunstâncias em que as uso, e a OOP tornaria mais difícil/tedioso chegar à funcionalidade principal do que está ocorrendo.

Acredito que um modelo híbrido de objetos, quando útil, e processual, quando prático, é o método de codificação mais eficaz.É uma pena que tenhamos todas estas guerras religiosas onde as pessoas defendem a utilização de um método em detrimento dos outros.Ambos são bons e ambos têm seu lugar.Na maioria das vezes, há 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).

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 já vale ouro na arte de construir software.

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

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

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

Projetos 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, reclamações de seguros e outras coisas, acho que essas coisas do mundo real são objetos.Tenho uma pilha na minha mesa, então devem ser reais.

O objetivo da OOP é fornecer ao programador outro meio de descrever e comunicar uma solução para um problema em 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 significa no código por meio de regras que são aplicadas na linguagem OO.

Ao contrário de muitos argumentos sobre este tópico, os conceitos 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 aproximarão os recursos dos objetos mesmo em linguagens não-OO.

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

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top