OOP cumpre a promessa de reutilização de código? Quais alternativas existem para obter a reutilização de código?


56

Talvez a maior promessa do uso de paradigma orientado a objetos seja a reutilização de código. Alguns contestam que isso foi alcançado. Por que foi (não) alcançado?

A reutilização de código como OOP define, torna os projetos mais produtivos?

Ou mais gerenciável? Ou mais fácil de manter? Ou com mais qualidade?

Provavelmente todos concordamos que a reutilização de código é uma coisa boa, mas existem várias maneiras de atingir esse objetivo. A questão é sobre o método de reutilização de código oferecido pelo OOP. Foi uma coisa boa? Existem métodos melhores para obter a reutilização de código do que a orientação a objetos, subclassificação, polimorfismo etc.? Que maneiras são melhores? Por que ?

Conte-nos sua experiência com a reutilização de POO ou com a reutilização de outros paradigmas.



7
É complementar, não exatamente duplicado. Eu reformulei para entender melhor a diferença.
Maniero

Se você pode votar e achar que essa é uma pergunta útil ou que possui respostas úteis abaixo, vote. Os sites StackExchange precisam de votos para criar uma boa comunidade. Você pode dar 30 votos por dia, não os desperdice. Especialmente usuários com alta reputação e baixa contagem de votos, por favor leia isto: meta.programmers.stackexchange.com/questions/393/…
Maniero


2
@j_random_hacker: leia os comentários.
Maniero

Respostas:


34

A reutilização de código é uma boa idéia. Não é ótimo .

Eu tenho uma perspectiva extraída de cerca de 30 anos de engenharia de software, tentando "reutilizar".

Comecei a investigar a "reutilização de código" como um tópico de pesquisa nos anos 80, depois de descobrir que havia reutilizado o design de um SO que construí no início dos anos 70, para outro SO que construí no final dos anos 70.

A boa parte da reutilização de código é a capacidade de, às vezes, reutilizar código preexistente honesto com Deus. Mas o mundo está cheio de código; como pode encontrar o que você quer? Aqui está o que eu chamo de maldição de reutilização :

Eu sou o Papai Noel (ok Open Source) e tenho um pacote de 1 bilhão de componentes de software. Você pode ter qualquer um deles.

Boa sorte para escolher.

Para resolver bem o problema de reutilização:

  • o reutilizador precisa especificar de alguma forma o que ele precisa (funcional, desempenho, idioma de destino, suposições do ambiente, ...)
  • deve haver uma biblioteca de código "reutilizável" que tenha sido indexada de várias maneiras por esses critérios em potencial
  • algum mecanismo deve existir para selecionar os elementos candidatos (em um bilhão de elementos, você não pode olhar para todos eles pessoalmente)
  • é necessário que haja uma maneira de caracterizar a que distância da especificação os candidatos escolhidos estão
  • algum processo regular deve existir para permitir que o reutilizador modifique o código reutilizável escolhido (aqui está a maior contribuição do OOP: você pode editar um componente / objeto existente substituindo seus slots. OOP não fornece nenhuma outra ajuda).
  • tudo isso deve ser claramente mais barato do que simplesmente recodificá-lo

Principalmente o que foi descoberto ao longo dos anos é que, para que o código seja reutilizável, ele deve ser projetado para esse fim ou contém muitas suposições implícitas. As bibliotecas de reutilização de código mais bem-sucedidas foram realmente muito pequenas. Indiscutivelmente, bibliotecas e estruturas são códigos "reutilizáveis" e são extremamente bem-sucedidos; Java e C # são bem-sucedidos não porque são boas linguagens de computador, mas porque têm enormes bibliotecas bem projetadas, implementadas e documentadas disponíveis. Mas as pessoas não olham o código fonte nas bibliotecas; eles simplesmente chamam uma API bem documentada (projetada para ser geralmente utilizável).

O que a reutilização de código não fez (OOP também) é fornecer ordens de melhoria de magnitude em nossa capacidade de codificar sistemas.

Eu acho que a principal falha é que qualquer tipo de reutilização de código é fundamentalmente limitado porque o código tem muitas suposições embutidas . Se você reduz o código, minimiza as suposições, mas o custo para construir do zero não é muito grande e os ganhos de reutilização não são eficazes. Se você criar enormes pedaços de código, eles serão praticamente inúteis em um novo contexto. Como Gulliver, eles estão amarrados à praia por um milhão de cordas minúsculas, e você simplesmente não pode se dar ao luxo de cortar todas elas.

O que devemos trabalhar é a reutilização do conhecimento para construir código . Se pudermos fazer isso, podemos aplicar esse conhecimento para construir o código necessário, manipulando o conjunto atual de suposições.

Para fazer isso, ainda é necessário o mesmo recurso de especificação para caracterizar componentes de software (você ainda precisa dizer o que deseja!). Mas você aplica esse conhecimento de "construção" às especificações para gerar o código desejado.

Como comunidade, ainda não somos muito bons nisso. Mas as pessoas fazem isso o tempo todo; por que não podemos automatizar isso? Há muita pesquisa, e isso mostra que isso pode ser feito em muitas circunstâncias.

Uma parte importante do mecanismo necessário para isso são as ferramentas mecânicas para aceitar "descrições de componentes" (esses são apenas documentos formais e podem ser analisados ​​como linguagens de programação) e aplicar transformações de programa a eles.

Os compiladores já fazem isso: -} E eles são realmente bons na classe de problemas que enfrentam.

Modelos UML com geração de código são uma tentativa de fazer isso. Não é uma tentativa muito boa; praticamente o que se diz na maioria dos modelos UML é "Eu tenho dados parecidos com este". Muito difícil gerar um programa real se a funcionalidade for deixada de fora.

Estou tentando criar sistemas práticos de transformação de programas, uma ferramenta chamada DMS . Fiquei bastante distraído com a aplicação de transformações de programa, não tanto para abstrair especificações para gerar código, mas para codificar legado para limpá-lo. (Estes são o mesmo problema no resumo!). (Construir essas ferramentas leva muito tempo; eu faço isso há 15 anos e nesse meio tempo você tem que comer).

Mas o DMS tem as duas propriedades principais que descrevi acima: a capacidade de processar especificações formais arbitrárias e a capacidade de capturar o "conhecimento de geração de código" à medida que se transforma e aplicá-las sob demanda. E notavelmente, nós geramos em alguns casos especiais, algum código bastante interessante a partir das especificações; O DMS é amplamente construído usando-se para gerar sua implementação. Isso alcançou para nós pelo menos parte da promessa de reutilização (conhecimento): ganhos de produtividade extremamente significativos. Eu tenho uma equipe de cerca de 7 pessoas técnicas; nós escrevemos provavelmente 1-2 MSLOC de "especificações" para DMS, mas temos cerca de 10MSLOC de código gerado.

Resumo: a reutilização do conhecimento de geração é a vitória, não a reutilização de código .


4
IMHO, a melhor resposta. O importante é reutilização de conhecimento / idéia, não o código.
Kravemir

4
Mostly what has been discovered over the years is that for code to be reusable, it sort of has to be designed for that purpose, or it contains too many implicit assumptions.Cheguei a uma conclusão semelhante, mas não consegui expressá-la de maneira tão sucinta.
biziclop

36

A reutilização de código é alcançada no OOP, mas também na programação funcional. Sempre que você pegar um bloco de código e torná-lo exigível pelo resto do seu código, de modo que você possa usar essa funcionalidade em outro lugar, será reutilizado.

Esse tipo de reutilização de código também torna o código mais gerenciável, pois a alteração desse bloco solicitável altera todos os locais para os quais é chamada. Eu diria que esse resultado também aumentou a qualidade e a legibilidade.

Não tenho certeza de que o OOP esteja lá simplesmente para fornecer a reutilização de código. Considero o POO mais uma maneira de interagir com objetos e abstrair os detalhes da estrutura de dados.

Da Wikpedia:

A programação orientada a objetos tem raízes que podem ser encontradas nos anos 60. À medida que o hardware e o software se tornaram cada vez mais complexos, a capacidade de gerenciamento tornou-se uma preocupação. Os pesquisadores estudaram maneiras de manter a qualidade do software e desenvolveram a programação orientada a objetos em parte para resolver problemas comuns, enfatizando fortemente unidades discretas e reutilizáveis ​​da lógica de programação [citação necessário]. A tecnologia concentra-se nos dados e não nos processos, com programas compostos por módulos auto-suficientes ("classes"), cada instância da qual ("objetos") contém todas as informações necessárias para manipular sua própria estrutura de dados ("membros"). Isso contrasta com a programação modular existente, dominada por muitos anos, focada na função de um módulo, e não especificamente nos dados, mas também fornecendo reutilização de código, e unidades reutilizáveis ​​auto-suficientes da lógica de programação, permitindo a colaboração através do uso de módulos vinculados (sub-rotinas). Essa abordagem mais convencional, que ainda persiste, tende a considerar dados e comportamento separadamente.


9
A programação funcional +1 pode ser o caminho a seguir para a reutilização de código.
Jonas

11
@ Matthieu M .: Bem, como é reutilizável double sqrt (double x)? Funções puras são o arquétipo da reutilização.
Joonas Pulakka

3
@Joonas: double sqrt(double x), float sqrt(float x), int sqrt(int x)você pode definir um monte deles, enquanto que com uma linguagem de programação genérica você teria Number sqrt(Number x)e ser feito com ele.
precisa

11
@ Matthieu M .: De fato, os genéricos reduzem a replicação de código, então é "mais reutilizável", sim. No entanto, acho que a chave real para a reutilização é definir funções simples, pequenas, sãs e puras (essa é a direção da "programação funcional") e repassá-las, o que é possível em C. É mais sobre o estilo de programação geral do que sobre os recursos da própria linguagem.
Joonas Pulakka

11
@Joonas: Ah, eu tinha perdido a palavra pura , você está certo, compor pequenas funções puras é ótimo, e até C possui indicadores de funções para isso.
Matthieu M.

15

Sim e não

A reutilização de código é um termo genérico para muitas atividades diferentes.

  1. Reutilização de código em um único projeto. OO é perfeitamente adequado para isso, um aplicativo bem projetado mapeará de perto os relacionamentos do mundo modelado, eliminando o código duplicado o máximo possível e aconselhável. No entanto, você pode argumentar que as tecnologias pré-OO podem alcançar a mesma coisa, o que é verdade, mas o OO é, de muitas maneiras, mais conveniente.
  2. Bibliotecas de terceiros Isso parece funcionar igualmente bem com ou sem OO.
  3. Reutilização de código multiuso A maior promessa de reutilização de código do OO foi que o código, uma vez escrito para um aplicativo, pode ser reutilizado posteriormente para outro, para o qual não foi projetado especificamente. Essa foi toda a raiva quando a noção de OO se infiltrou pelas portas dos escritórios superiores de administração, e o OO falhou completamente em alcançá-lo. Aconteceu que esse objetivo era um aspecto crucial do design do OO (e possivelmente todo o código processual, mas essa é apenas a minha teoria) e as tentativas de redirecionar o código terminaram em desastres de manutenção. (Os conhecidos padrões de uma estrutura antiga que ninguém se atreve a modificar e seus amigos, as estruturas ligeiramente diferentes para cada aplicativo geralmente surgem daqui.)

13

Eu postaria uma resposta longa, mas por quê? Udi Dahan explica isso muito melhor do que eu.

http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/

Aqui está o começo do post:

Este setor está pré-ocupado com reutilização.

Há uma crença de que se apenas reutilizássemos mais código, tudo seria melhor.

Alguns chegam a dizer que todo o ponto de orientação a objetos era reutilização - não era, encapsulamento era o grande problema. Depois dessa orientação, o componente deveria fazer com que a reutilização acontecesse. Aparentemente, isso também não foi tão bom, porque agora estamos depositando nossas esperanças reutilizáveis ​​na orientação a serviços.

Livros inteiros de padrões foram escritos sobre como alcançar a reutilização com a orientação do dia. Os serviços foram classificados de todas as formas na tentativa de conseguir isso, desde serviços de entidade e serviços de atividade, passando por serviços de processo e serviços de orquestração. A composição de serviços foi apontada como a chave para reutilizar e criar serviços reutilizáveis.

É melhor eu deixar você contar o segredinho sujo:

Reutilizar é uma falácia


4
-1. O Sr. Dahan está preocupado com homens de palha; ninguém reutiliza seriamente o código não genérico, como ele implica, e se você remover esse argumento do artigo dele, ele é de fato a favor ou reutiliza o código adequadamente .
Steven A. Lowe

3
@ Steven A. Lowe Bem, eu gostaria que isso fosse verdade. Eu gostaria de ter sua sorte, porque eu vi a reutilização de código na forma não genérica. Não foi bonito.
Tony

11
Tenho certeza de que não era - mas eles estavam falando sério ? dilbert.com/strips/comic/1996-01-31
Steven A. Lowe

11
Concordado, o custo de tornar o código reutilizável é realmente alto, portanto, não compensa, a menos que você esteja falando na escala das classes base Java ou .NET. Veja youtube.com/watch?v=aAb7hSCtvGw
Andomar

13

Concordo com Chris, a programação funcional é uma boa maneira de reutilizar o código.

Muitos programas possuem estruturas de código recorrentes. Para isso, alguns padrões de design são usados ​​no mundo OOP, mas isso pode ser alcançado por funções recursivas e correspondência de padrões em linguagens de programação funcionais. Para mais informações, consulte o primeiro capítulo em Programação Funcional do Mundo Real .

Eu acho que a herança profunda no POO pode ser enganosa em muitos casos. Você tem uma classe e muitos dos métodos intimamente relacionados são implementados em arquivos diferentes. Como Joe Armstrong disse sobre OOP:

O problema com linguagens orientadas a objetos é que eles têm todo esse ambiente implícito que carregam consigo. Você queria uma banana, mas o que conseguiu foi um gorila segurando a banana e toda a selva.

As funções de alta ordem também são muito úteis quando se trata de reutilização de código, por exemplo, mape foldressa é a base do MapReduce do Google .

A passagem de mensagens assíncronas também é uma boa maneira de organizar software complexo, e alguns cientistas da computação afirmam que objetos foram assumidos para se comunicar entre si de forma assíncrona como no Tell, não pergunte ao princípio de POO. Veja mais sobre isso em Programação Orientada a Objetos: O Caminho Errado? foram Joe Armstrong é citado:

Comecei a pensar sobre o que era programação orientada a objetos e pensei que Erlang não era orientado a objetos, era uma linguagem de programação funcional. Então, meu supervisor de tese disse: "Mas você está errado, Erlang é extremamente orientado a objetos". Ele disse que as linguagens orientadas a objetos não são orientadas a objetos. Posso pensar, embora não tenha certeza se acredito ou não, mas Erlang pode ser a única linguagem orientada a objetos, porque os três princípios da programação orientada a objetos são que ela se baseia na passagem de mensagens , que você tem isolamento entre objetos e tem polimorfismo .

A passagem assíncrona de mensagens como nos sistemas controlados por eventos e em Erlang também é uma maneira muito boa de desacoplar sistemas e o acoplamento solto é importante em sistemas complexos. Com um sistema suficientemente desacoplado, você pode evoluir o sistema enquanto estiver em execução, talvez em nós diferentes. A Unibet fez uma ótima apresentação sobre isso: Arquitetura Orientada a Eventos de Domínio

No entanto, acho que a maior parte da reutilização de código é feita usando bibliotecas e estruturas.


2
Eu amo essa citação de gorila. ^^
gablin

Eu pensei que a pergunta era sobre reutilização de código, não semântica agradável ..?
Daniel Lubarov

6

O humilde canal unix fez mais pela reutilização de código do que qualquer outra coisa que veio e se foi. Os objetos eram uma maneira intuitiva de estruturar o código quando eles surgiam e, mais tarde, as pessoas começaram a aderir a tudo e qualquer coisa. Em geral, os objetos são para encapsulamento e não para reutilização de código, a reutilização de código exige algo mais e a hierarquia de herança de classe é um substituto inadequado para o que realmente deveria ser um mecanismo de reutilização de código.


4

OOP não é especial; você pode criar código reutilizável com ou sem OOP. As funções puras são particularmente reutilizáveis : por exemplo, java.lang.math.sqrt(double)insere um número e fornece um número. Sem POO, mas definitivamente mais reutilizável do que a maioria dos códigos existentes.


4

Do ponto de vista da programação funcional, o POO é principalmente sobre o gerenciamento de estado.

Na programação funcional, você pode facilmente ter centenas de funções úteis para listas: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html .

Você teria centenas de métodos em uma classe List? Os métodos públicos são considerados uma interface para o estado interno que você deseja manter pequeno.

Infelizmente, em vez de (re) usar muitas funções pequenas, algumas pessoas duplicam a funcionalidade. Para mim, isso ocorre porque o OOP não incentiva a reutilização de código tanto quanto a programação funcional.


11
Suas conclusões estão todas erradas, @ Lenny222. Não há nada sobre OOP que exija classes para manter o estado. Essa é uma questão de sua arquitetura, se ela armazena o estado internamente ou, como as classes Integer do Smalltalk, instancia novos objetos com o novo estado.
Huperniketes

11
Lamento não ter me expressado de maneira a evitar esse mal-entendido: o que eu quis dizer é que a diferença entre OOP e FP não é que OOP incentive a reutilização de código mais do que FP (o que o título implica). Eu experimentei uma reutilização de código muito melhor com o FP. Se você tem apenas classes imutáveis, está imitando FP, por que OOP em primeiro lugar? No meu POV, trata-se de um gerenciamento imperativo do estado.
LennyProgrammers

3

Para mim, sim, mas não o tempo todo, e isso poderia ter sido feito de outras maneiras.

Na maioria das vezes, criando uma classe base abstrata e implementações concretas dessa classe.

Muitas estruturas também usam a herança para fornecer reutilização de código (Delphi, Java, .Net são apenas algumas que vêm à mente instantaneamente).

Isso não quer dizer que muitas bibliotecas de utilitários e trechos de código também não poderiam ter funcionado, mas há algo agradável em uma hierarquia de objetos bem projetada.


3

Na minha experiência, tive mais sucesso ao alavancar códigos "reutilizáveis" por meio de recursos de programação genéricos (como modelos C ++) do que usando princípios de OOP, como hierarquias de herança.


2

OOP está muito aberto para reutilização efetiva.

Existem muitas maneiras de reutilizar. Cada classe pública pergunta: "faça de mim uma nova instância!" , cada método público diz: "me ligue!" , cada método protegido produz: "substitua-me!" - e todas essas formas de reutilização são diferentes , possuem parâmetros diferentes, aparecem em contextos diferentes, todas têm regras diferentes, como chamar / estender / substituir.

A API é melhor, é um subconjunto estrito de pontos de POO (ou não), mas na vida real, as APIs são excessivamente caras e crescem para sempre, ainda há muitos pontos de conexão. Além disso, uma boa API pode facilitar a vida, é a melhor maneira de fornecer interface para OOP.


O paradigma Datadlow fornece uma interface estrita para componentes, eles têm portas dos seguintes tipos:

  • consumidores (insumos) e
  • produtores (produtos).

Depende do domínio, existem alguns tipos de pacotes, para que consumidores e produtores possam ser conectados, se tiverem as mesmas portas (ou compatíveis). A parte mais bonita, que pode ser feita visualmente, porque não há parâmetros ou outros ajustes nas conexões, eles realmente apenas conectam um consumidor e um produtor.

Eu estava um pouco confuso, você pode dar uma olhada na tag "dataflow" no StackOverflow , ou "programação de fluxo de dados" da Wikipedia ou "programação baseada em fluxo" da Wikipedia .

(Além disso, escrevi um sistema de fluxo de dados em C ++. Portanto, OOP e DF não são inimigos, o DF é uma forma de organização de nível superior.)


2

No CommonLisp, existem muitos meios para obter reutilização:

  • digitação dinâmica, tendo seu código genérico por padrão

  • abstrações imperativas, ou seja, sub-rotinas

  • orientação a objeto, com herança múltipla e despacho múltiplo

  • abstração de sintaxe, a capacidade de definir novas construções sintáticas ou abreviar o código da placa da caldeira

  • abstrações funcionais, fechamentos e funções de alta ordem

Se você tentar comparar a experiência CommonLisp para outras línguas, você verá que a principal característica que flexibiliza a reutilização de código é a presença de ambas as abstrações orientadas a objetos e funcional. Eles são mais complementares que alternativos: sem um deles, você é forçado a reimplementar os recursos ausentes de uma maneira desajeitada. Veja, por exemplo, classes de functor usadas como fechamentos e correspondência de padrões para obter despacho de método não extensível.


1

Realmente não existe "reutilização" da maneira como as pessoas a descrevem. A reutilização é uma propriedade acidental de qualquer coisa. É difícil planejar isso. O que a maioria das pessoas quer dizer quando fala sobre "reutilização" é "uso". É um termo muito menos atraente e emocionante. Quando você usa uma biblioteca, está usando-a normalmente para o que foi planejada. Você não a está reutilizando, a menos que esteja fazendo algo realmente louco com ela.

Nesse sentido, a reutilização no mundo real tem a ver com reaproveitar as coisas. Posso reutilizar esses assentos aqui e reorganizá-los para formar ... uma cama! Não é uma cama muito confortável, mas posso fazer isso. Esse não é o uso principal deles. Estou reutilizando-os fora do domínio original de aplicabilidade. [...] Amanhã voltarei para o Reino Unido. Vou não reutilizar o plano. Vou usá-lo apenas para o propósito a que se destina, não há nada de fantasia ou empolgação nisso.

- Kevlin Henney


3
As pessoas vão acreditar em tudo que vêem impresso. Kevlin Henney está incorreto e baseou seu raciocínio na falta de contexto histórico e na má interpretação semântica. Reutilizar código era um princípio fundamental de programação desde os dias dos computadores UNIVAC e IBM a vácuo. Reutilizar o código não significa reutilizá-lo para alguma funcionalidade diferente daquela para a qual foi planejado . Você escreveu e montou (posteriormente foi compilada) suas sub-rotinas para produzir código de objeto que foi então vinculado ao seu programa. Reutilizar realmente significa o que é comumente considerado hoje no setor.
Huperniketes

Se você escrever duas funções que fazem exatamente a mesma coisa, você NÃO reutilizou o código, independentemente de quantas vezes você as usou.
JeffO

A analogia da cadeira é agradável e tudo mais, exceto apenas uma palavra: Lego.
precisa saber é

1

Vou arriscar o ridículo e confessar, só tenho usado o OOP muito recentemente. Não vem automaticamente para mim. A maior parte da minha experiência envolve bancos de dados relacionais, por isso penso em tabelas e junções. Há alegações de que é melhor aprendê-lo desde o início, o que evita a necessidade de religar seu pensamento quando se trata de programação. Não tenho esse luxo e me recuso a abandonar minha carreira por causa de alguma teoria da torre de marfim. Como todo o resto, eu vou descobrir.

No começo, pensei que todo o conceito não fazia sentido. Pareceu-me desnecessário e demais. Eu sei, isso é conversa maluca. Obviamente, é preciso um certo nível de entendimento antes que você possa apreciar os benefícios de qualquer coisa ou descartá-lo por métodos melhores.

A reutilização de código exige uma disposição para não repetir o código, um entendimento de como realizá-lo e um planejamento inicial. Você deve evitar reutilizar o código quando decidir ter um caso em que simplesmente não vale a pena? E nenhuma linguagem é tão estritamente OO que gera um erro quando pensa que você deveria ter herdado o código de outra classe. Na melhor das hipóteses, eles fornecem um ambiente propício à sua implementação.

Eu acho que o maior benefício do OOP é a aceitação geral de como o código deve ser organizado. Tudo o resto é molho. Uma equipe de programadores pode não concordar totalmente sobre como todas as classes devem ser estruturadas, mas eles devem ser capazes de encontrar o código.

Já vi código processual suficiente para saber que poderia estar em qualquer lugar e, às vezes, em todo lugar.


"E nenhuma linguagem é tão estritamente OO que gera um erro quando pensa que você deveria ter herdado código de outra classe" - ainda não, de qualquer maneira!
Steven A. Lowe

1

OOP oferece mais maneiras de reutilizar o código. Isso é tudo.


OOP também promove a reutilização da interface e a reutilização do design.
Rwong

Isso me dá muito menos maneiras de escrever um código genérico, reutilizável e altamente abstrato do que os outros paradigmas, como programação funcional (curadoria de mente, bibliotecas combinadoras, etc.) e metaprogramação. Na verdade, OOP parece ter um nível de abstração, quando as alternativas não são limitadas.
SK-logic

@ SK-logic: ortogonal.
Steven A. Lowe

1

Reutilização Horizontal: aspectos, características, enxertos

Às vezes, o OO clássico fica aquém da reutilização de código, especialmente quando você enlouquece toda a herança por falta de uma maneira melhor de compartilhar a funcionalidade real entre as classes. Para esse problema, foram criados mecanismos de reutilização horizontal, como AOP, características e enxertos.

Programação Orientada a Aspectos

Considero AOP como a meia laranja desaparecida da OOP. AOP não é tão conhecido, mas chegou ao código de produção.

Vou tentar explicar em termos simples: imagine que você pode injetar e filtrar funcionalidades com uma estrutura especial chamada aspecto, esses aspectos possuem "métodos" que definem o que e como serão afetados pela reflexão , mas em tempo de compilação , esse processo é chamado de tecelagem .

Um exemplo seria um aspecto que diz "para todos os métodos de determinadas classes que começam com get, o programa gravará em um arquivo de log os dados que foram obtidos e a hora em que foram obtidos".

Assista a essas duas palestras se quiser entender melhor a AOP:

Traços e Enxertos

Os traços são outra construção para definir o código reutilizável que complementa o OOP, eles são semelhantes a mixins , mas mais limpos.

Em vez de explicá-los, há um ótimo RFC PHP que explica os dois . Traços estão chegando ao PHP, já estão comprometidos com o tronco.

Em suma

OOP é fundamental na modularidade, ainda assim, na minha opinião e como normalmente a conhecemos hoje, o OOP ainda está incompleto .


0

OOP Fornece um conjunto de ferramentas úteis que permitem escrever código que pode ser usado em mais locais do que você poderia ter sem essas ferramentas. Se você escrever uma PrintItfunção que pega qualquer objeto antigo e o chama .toString(), você terá reutilizado esse código assim que o chamar com mais de um tipo de objeto. Com essas ferramentas, cada linha de código faz mais.

A programação funcional está muito quente no momento entre os descolados. Fornece-lhe um todo separado de ferramentas para fazer com que cada linha de código faça mais. Provavelmente não é melhor ou funciona, mas fornece outra ferramenta na caixa de ferramentas.

(Havia uma ideia maluca para todo um nível extra de reutilização orientada a objetos: a idéia era que poderíamos definir uma única Customerclasse e usá-la em todos os aplicativos que escrevemos. Então, os aplicativos seriam apenas um pouco de cola aqui e ali. não funcionou. Mas isso não significa que o OO falhou ou até mesmo a reutilização falhou. Os tipos básicos de código reutilizados nos aplicativos tornaram possível escrever aplicativos que fizeram mais e escrevê-los mais rapidamente.)


0

Lendo as postagens acima, algumas observações:

  • Muitos pensam que a reutilização de código no OOP implica herança. Eu não concordo. Interfaces e contratos são o núcleo para codificar a reutilização em sistemas OOP. OOP é uma tentativa de caixa cinza na criação de uma tecnologia de componentes.
  • A diferença entre "estruturas" específicas de domínio e genéricas como assunto de reutilização me parece muito abstrata. Na minha opinião, um componente (um contrato de interface conciso, mínimo e reutilizável e a implementação por trás) só pode ser feito se o problema abordado for bem compreendido. Um componente específico do domínio, que permite que especialistas não pertencentes ao domínio realizem seu trabalho com menos conhecimento sobre o domínio, é um componente (re) útil. Os usuários precisam entender a interface, menos os meandros do domínio do problema.
  • Níveis de reutilização frequentemente esquecidos: reutilização de ideias, reutilização de especificações, reutilização de arquitetura / design, reutilização de interface, reutilização de casos de teste. A reutilização de código nem sempre é favorável. Mas é uma grande economia de tempo manter uma arquitetura específica para enfrentar um produto novo e similar.
  • Os padrões de Design da OOP (Gamma et al.) Aos meus olhos elaboraram técnicas de implementação tática, em vez de serem significativas no contexto da reutilização de código em uma escala maior. Eles ajudam a escrever um aplicativo com elementos OOP, mas eu não os via como uma solução para a questão "reutilização de código" além de um único aplicativo.
  • Talvez não seja justo: 20 anos de experiência em C / C ++ / C # e 6 meses de programação funcional (F #). Um elemento importante para permitir a reutilização é: As pessoas precisam encontrar facilmente "a interface", estudá-la, entendê-la e usá-la. A programação funcional pura não me facilita ver a estrutura, os candidatos a reutilização ou onde tudo começa e onde tudo termina. O tão elogiado "açúcar sintático" geralmente é sal nos meus olhos, impedindo-me de ver facilmente o que acontece. Assim, eu provavelmente tentaria reutilizar um funcional (o que é isso - várias funções?), Que podem ter efeitos colaterais ocultos que eu nem consigo ver (avaliação preguiçosa, mônadas, ...). Não me interpretem mal, a programação funcional tem lados muito interessantes, mas todos os pontos fortes proclamados vejo com uma boa dose de dúvida.
  • Especificação, Design, Implementação são acoplados, mas não podem ser vistas facilmente atravessáveis ​​na "mesma coisa". Muito mais vital para o aumento da produtividade futura do que um novo paradigma de programação é, fechar a lacuna, aumentar (raciocínio automatizado, rastreabilidade) os benefícios mútuos entre essas visões. Linguagens de especificação formalizadas, notações de teste padronizadas (por exemplo, ttcn3) e linguagens de programação que suportam a verificação de interfaces e contratos em relação às especificações, sem exigir comentários.

0

O problema é mais sutil:

  1. OOP é um ótimo método para estruturar código com estado mutável . Ao encapsular o estado em objetos, o código imperativo do statefull se torna mais compreensível, porque, por exemplo, se um pedaço de estado é expresso como campos particulares de uma classe, você sabe que pelo menos esse pedaço de estado específico só pode ser modificado pelos métodos deste classe. (E você pode facilmente quebrar esse benefício abusando da herança, btw.) Isso já é suficiente, mas é melhor do que não ter isso.
  2. código com estado mutável é inerentemente difícil de reutilizar . Muito mais difícil do que o código usando estruturas de dados imutáveis.

Portanto, o POO em si não é ruim do ponto de vista do código reutilizável , mas os tipos de código que são escritos usando o OOP são inerentemente difíceis de reutilizar .

Além disso, a programação funcional pode resultar em código mais reutilizável . Mas obter as abstrações corretamente para escrever um código funcional sensato e cumprir um prazo pode não ser possível. E abstrações "semi-direitas" serão mais fáceis de expressar o estilo OOP. E isso não tenderá a resultar na reutilização mais fácil do código - um nível mais alto de abstrações significa que o entendimento do código exigirá um investimento inicial mais alto da capacidade cognitiva limitada dos programadores.

Como um exemplo prático: o código do jogo envolve muitos estados mutáveis, porque essa é a maneira natural de pensar em codificar um jogo, a menos que seja muito enigmático / algorítmico, portanto, obviamente, acaba sendo estruturado usando OO. E é claro que é difícil reutilizar. Mas o mesmo código, contendo o mesmo conhecimento, seria ainda mais difícil de reutilizar sem OOP . E reescrevê-lo para ser um estilo funcional pode precisar mudar totalmente a maneira como você pensa sobre esse código, o conhecimento por trás dele. Sim, o conhecimento resultante por trás do código seria muito mais claro após a reescrita do OO ao FP, talvez ... mas o custo pode ser enorme e pode sero tipo de custo que também teria que ser pago pelas pessoas que desejam reutilizar o código incrivelmente inteligente e bem abstrato com o qual você acaba, paradoxalmente, as pessoas acabariam não reutilizando o código, mesmo que tecnicamente seja mais reutilizável.

... o que leva à última sutileza: a reutilização do código é sobre a interface People | Code , não apenas sobre o código. OOP faz um trabalho decente ao servir essa interface, porque mapeia bem o número de pessoas que pensam em muitos tipos de código escritos atualmente. O FP pode ser melhor para a reutilização de código, mas não para reutilizar facilmente o tipo de código que as pessoas realmente precisam escrever atualmente.Isso mudará conforme o tipo de código que precisamos escrever.

PS E se alguém quiser dizer que "OO não é sobre estado mutável, você também pode ter OO com estado imutável" ... Eu chamo isso de "FP usando classes como espaços de nome". É ótimo quando funciona para você e evita algumas falhas nos sistemas de módulos de alguns idiomas e pode resultar em código mais reutilizável. Mas isso não é OO;)

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