Pergunta

Pelo que eu entendo, OOP é o paradigma mais comumente usado para projetos de grande escala. Sei também que alguns subconjuntos menores de grandes sistemas utilizam outros paradigmas (por exemplo, SQL, que é declarativa), e eu também perceber que em níveis mais baixos de OOP computação não é realmente viável. Mas parece-me que, geralmente, os pedaços de soluções de nível superior são quase sempre juntos de uma forma OOP.

Existem cenários em que um paradigma realmente non-OOP é realmente uma melhor escolha para uma solução em larga escala? Ou isso é inédito nos dias de hoje?

Eu me perguntei isso desde que eu comecei a estudar CS; é fácil de obter a sensação de que OOP é algum nirvana de programação que nunca será superada.

Foi útil?

Solução

Na minha opinião, o OOP razão é usado tão amplamente não é tanto que é a ferramenta certa para o trabalho. Eu acho que é mais que uma solução pode ser descrito para o cliente de uma forma que eles entendem.

Um carro é um veículo que tem um motor. Essa é a programação e mundo real tudo em um!

É difícil de compreender qualquer coisa que pode caber a programação e mundo real tão elegantemente.

Outras dicas

Linux é um projeto de grande escala que é muito não OOP. E não teria muito a ganhar com isso também.

Eu acho que OOP tem uma boa anel para ele, porque tem-se associado com as boas práticas de programação como encapsulamento, ocultação de dados, a reutilização de código, et.c. modularidade Mas essas virtudes não são de forma única para OOP.

Você pode ter um olhar para Erlang, escrito por Joe Armstrong.

Wikipedia:

"Erlang é um general-purpose linguagem de programação concorrente e sistema de execução. O subconjunto sequencial de Erlang é uma linguagem funcional, com avaliação rigorosa, única atribuição e tipagem dinâmica ".

Joe Armstrong:

“Porque o problema com linguagens orientadas a objetos é que eles têm tem todo esse ambiente implícito que eles carregam com eles. Vocês queria uma banana, mas o que você conseguiu foi uma gorila segurando a banana eo toda selva.”

A promessa de OOP era a reutilização de código e manutenção mais fácil. Não estou certo de que ele entregue. Eu vejo as coisas como dot net como sendo o mesmo que as bibliotecas C que usamos para obter fro vários fornecedores. Você pode chamar isso de reutilização de código, se quiser. Quanto à manutenção código ruim é ruim código. OOP não ajuda.

Eu sou o maior fã de OOP, e eu pratico OOP todos os dias. É a maneira mais natural para escrever código, porque se assemelha a vida real.

Embora, eu percebo que a virtualização do OOP pode causar problemas de desempenho. Claro que isso depende do seu design, a linguagem e a plataforma que você escolheu (sistemas escritos em linguagens baseadas coleta de lixo, como Java ou C # pode um desempenho pior do que os sistemas que foram escritos em C ++, por exemplo).

Eu acho que em sistemas em tempo real, programação procedural pode ser mais apropriado.

Note que nem todos os projectos que pretendem ser OOP são, na verdade OOP. Às vezes, a maior parte do código é processual, ou o modelo de dados é anêmica , e assim por diante. ..

Zyx, você escreveu: "A maioria dos sistemas usam bancos de dados relacionais ..."

Eu tenho medo não existe tal coisa. O modelo relacional será de 40 anos no próximo ano e ainda não foi implementado. Eu acho que você quer dizer "bancos de dados SQL." Você deve ler qualquer coisa por Fabian Pascal para entender a diferença entre um SGBD relacionais e um DBMS SQL.

"... o modelo relacional é geralmente escolhido devido à sua popularidade,"

É verdade, é popular.

"... disponibilidade de ferramentas,"

Infelizmente, sem a principal ferramenta necessária:. Uma implementação do modelo relacional

"apoio"

Sim, o modelo relacional tem suporte bem, eu tenho certeza, mas é totalmente suportado por uma implementação dbms.

"eo fato de que o modelo relacional é na verdade um conceito matemático,"

Sim, é um conceito matemático, mas, não sendo implementadas, é em grande parte restrita às torres de marfim. A teoria das cordas é também um conceito matemático, mas eu não implementar um sistema com ele.

Na verdade, apesar de ele está sendo um conceito methematical, certamente não é uma ciência (como em ciência da computação) porque lhe falta o primeiro requisito de qualquer ciência: que é falsificável: não há nenhuma implementação de um SGBD relacionais contra a qual nós pode verificar suas reivindicações.

É óleo de cobra puro.

"... ao contrário do OOP."

E ao contrário do OOP, o modelo relacional nunca foi implementado.

Compre um livro sobre SQL e obter produtivo.

Deixe o modelo relacional para os teóricos improdutivas.

este e este . Aparentemente, você pode usar C # com cinco paradigmas de programação diferentes, C ++ com três, etc.

construção Software não é semelhante a física fundamental. Física esforçar para descrever a realidade usando paradigmas que podem ser desafiados por novos dados experimentais e / ou teorias. A física é uma ciência que procura uma "verdade", de maneira que a construção Software não.

construção de software é um negócios . Você precisa ser produtivo , ou seja, para atingir algumas metas para que alguém vai pagar dinheiro. Paradigmas são usados ??porque eles são úteis para produtos de software de forma eficaz . Você não precisa de todos concordem. Se eu fizer OOP e está funcionando bem para mim, eu não me importo se um paradigma "novo" seria potencialmente 20% a mais útil para mim se eu tivesse o tempo e dinheiro para aprender e depois repensar a estrutura de software inteiro I' m trabalhando e redesenhá-lo a partir do zero.

Além disso, você pode estar usando um outro paradigma e eu ainda vou ser feliz, da mesma forma que eu possa ganhar dinheiro executando um restaurante japonês alimentos e você pode ganhar dinheiro com um restaurante de comida mexicana ao lado. Eu não preciso discutir com você se comida japonesa é melhor do que comida mexicana.

Eu duvido OOP vai desaparecer tão cedo, ele só se encaixa em nossos problemas e modelos mentais muito bem.

O que estamos começando a ver que é multi-paradigma se aproxima, com idéias declarativas e funcionais sendo incorporados em projetos orientados a objetos. A maioria das línguas mais recentes da JVM são um bom exemplo disto (JavaFX, Scala, Clojure, etc.), bem como LINQ e F # na plataforma .NET.

É importante notar que eu não estou falando sobre a substituição OO aqui, mas sobre complementando-o.

  • JavaFX tem mostrado que uma declarativa solução vai além de SQL e XSLT, e também pode ser utilizado para a ligao propriedades e eventos entre o Visual componentes em uma GUI

  • Para tolerante a falhas e altamente sistemas concorrentes, funcionais programação é um muito bom ajuste, como demonstrado pela Ericsson AXD301 (programado usando Erlang)

Então ... como a concorrência se torna mais importante e FP se torna mais popular, imagino que as línguas não apoiar este paradigma vai sofrer. Isto inclui muitos que são atualmente populares, como C ++, Java e Ruby, embora JavaScript deve lidar muito bem.

Usando OOP torna o código mais fácil de gerir (como na atualização / Modificar / adicionar novos recursos) e entender. Isto é especialmente verdadeiro com projetos maiores. Porque módulos / objetos encapsular os seus dados e operações em que os dados é mais fácil de compreender a funcionalidade e a imagem grande.

O benefício de OOP é que é mais fácil discutir (com outros desenvolvedores / gestão / cliente) um LogManager ou OrderManager, cada um dos quais englobam funcionalidade específica, em seguida, descrevendo 'um grupo de métodos que despejar os dados no arquivo' e 'os métodos que mantêm a par de detalhes da ordem'.

Então eu acho que OOP é útil especialmente com grandes projetos, mas há sempre novos conceitos transformando-se de modo a manter a procura de novidades no futuro, avaliar e manter o que é útil.

As pessoas gostam de pensar em várias coisas como "objetos" e classificá-los, assim não há dúvida de que OOP é tão popular. No entanto, existem algumas áreas onde OOP não ganhou uma popularidade maior. A maioria dos sistemas usam bancos de dados relacionais em vez de objetivo. Mesmo se os segundos manter alguns registros notáveis ??e são melhores para alguns tipos de tarefas, o modelo relacional é unsually escolhido devido à sua popularidade, a disponibilidade de ferramentas, suporte e o fato de que o modelo relacional é na verdade um conceito matemático, ao contrário do OOP.

Outra área em que eu nunca vi OOP é o processo de construção de software. Todos os scripts de configuração e fazer são processuais, parcialmente por causa da falta do suporte para OOP em linguagens de shell, em parte porque OOP é demasiado complexo para tais tarefas.

opinião Ligeiramente controversa de mim, mas eu não encontrar OOP, pelo menos, de um tipo que é popularmente aplicado agora, ser que útil na produção do maior software escala em meu domínio particular (VFX , que é um pouco semelhante na organização cena e estado do aplicativo como jogos). Acho que é muito útil em um meio de escala menor. Eu tenho que ser um pouco cuidado aqui desde que eu convidou alguns mobs no passado, mas eu deveria qualificar que esta é na minha experiência estreita no meu tipo particular de domínio.

A dificuldade que eu encontrei frequentemente é que, se você tem todas estas pequenas concreto objetos encapsular dados, eles agora querem toda a conversa entre si. As interações entre eles pode ficar extremamente complexos, como assim (exceto muito, muito mais complexo em uma aplicação real que abrange milhares de objetos):

enter descrição da imagem aqui

E este não é um gráfico de dependência directamente relacionada com o acoplamento tanto como um "gráfico de interação". Não poderia haver abstrações de dissociar estes objetos concretos do outro. Foo pode não falar com Bar diretamente. Pode, em vez falar com ele através IBar ou algo desse tipo. Este gráfico seria Foo ainda de conexão para Bar uma vez que, apesar de ser desacoplado, eles continuam a falar um com o outro.

E tudo isso a comunicação entre pequenas e médias objetos que compõem o seu próprio pequeno ecossistema, se aplicada a toda a escala de uma grande base de código em meu domínio, pode tornar-se extremamente difícil de manter. E torna-se tão difícil de manter, porque é difícil raciocinar sobre o que acontece com todas essas interações entre objetos com relação a coisas como efeitos colaterais.

Em vez disso o que eu encontrei útil é organizar a base de código geral em subsistemas completamente independentes, pesadas que acessam um "banco de dados" central. Cada subsistema em seguida, entradas e saídas de dados. Alguns outros subsistemas pode acessar os mesmos dados, mas sem qualquer sistema de um falar diretamente uns aos outros.

enter descrição da imagem aqui

... ou isto:

enter descrição da imagem aqui

... e cada sistema individual tentativas não mais para encapsular estado. Não tente tornar-se seu próprio ecossistema. Em vez disso lê e grava dados no banco de dados central.

É claro que na implementação de cada subsistema, eles podem usar um número de objetos para ajudar a implementar-los. E é aí que eu acho OOP muito útil é na implementação desses subsistemas. Mas cada um desses subsistemas constitui uma relativamente médio e projeto de pequena escala, não muito grande, e é nesse meio para escala menor que acho OOP muito útil.

"linha de montagem de programação" Com conhecimento mínimo

Isso permite que cada subsistema de se concentrar apenas em fazer a sua coisa com quase nenhum conhecimento do que está acontecendo no mundo exterior. Um desenvolvedor com foco em física pode apenas sentar-se com o subsistema física e sabem pouco sobre como o software funciona, exceto que há uma base de dados central a partir do qual ele pode recuperar coisas como componentes de movimento (apenas dados) e transformá-los através da aplicação física para que os dados. E isso faz seu trabalho muito simples e faz com que seja assim ele pode fazer o que ele faz melhor com o mínimo conhecimento de como funciona Tudo o resto. central de dados de entrada e saída de dados central: isso é tudo cada subsistema tem que fazer corretamente para tudo o mais ao trabalho. É a coisa mais próxima que eu encontrei no meu campo de "montagem de programação line"onde cada desenvolvedor pode fazer seu trabalho com conhecimento mínimo sobre o funcionamento do sistema em geral.

O teste ainda é também bastante simples por causa do foco estreito de cada subsistema. Nós já não está zombando de objetos concretos com injeção de dependência tanto quanto gerando uma quantidade mínima de dados relevantes para um determinado sistema e testar se o sistema particular fornece a saída correta para uma determinada entrada. Com tão poucos sistemas para teste (apenas dezenas pode fazer-se um software complexo), também reduz o número de testes necessários substancialmente.

Quebra encapsulamento

O sistema, então, se transforma em um oleoduto bastante plana transformando o estado do aplicativo central através subsistemas independentes que são praticamente alheio à existência um do outro. Pode-se, por vezes, empurrar um evento central ao banco de dados que outros processos do sistema, mas que outro sistema ainda é alheio sobre onde esse evento veio. Eu encontrei esta é a chave para lidar com a complexidade, pelo menos em meu domínio, e é eficaz através de um sistema de entidade de componente.

No entanto, se assemelha a algo mais próximo de programação procedural ou funcional na escala ampla de dissociar todos estes subsistemas e deixá-los trabalhar com conhecimento mínimo do mundo exterior desde que nós estamos encapsulamento de ruptura, a fim de alcançar este objectivo e evitar a exigência de que os sistemas falar um com o outro. Quando você aumentar o zoom, então você pode encontrar a sua quota de objetos sendo usado para implementar qualquer um desses subsistemas, mas a uma escala mais ampla, os sistemas se assemelha a algo diferente de OOP.

Global Data

Eu tenho que admitir que eu estava muito hesitante em aplicar ECS, a princípio, um projeto arquitetônico em meu domínio uma vez que, em primeiro lugar, que não tinha sido feito antes para o meu conhecimento em competidores comerciais populares (3DS Max, SoftImage, etc) e, segundo, ele se parece com um monte de dados globalmente acessível.

eu encontrei, no entanto, que este não é um grande problema. Podemos ainda de forma muito eficaz manter invariantes, talvez até melhor do que antes. O motivo é devido à forma como a ECS organiza tudo em sistemas e componentes. Você pode estar certo de que um sistema de áudio não vai tentar transformar um componente de movimento, por exemplo, nem mesmo sob a hackiest de situações. Mesmo com uma equipe mal-coordenada, é muito improvável que a ECS irá degradar em algo que você não pode mais motivo sobre o qual o acesso sistemas de qual componente, já que é bastante óbvio no papel e praticamente não há razões que seja para um determinado sistema para o acesso uma inapropriado componente.

Ao contrário, muitas vezes removido muitas das antigas tentações para coisas hacky com os dados abertos, pois muitas das coisas hacky feito em nossa antiga base de código sob a coordenação e falta de tempo solta foi feito em tentativas precipitadas a abstrações de raios-x e tente acessar as partes internas dos ecossistemas de objetos. As abstrações começou a se tornar permeável, como resultado de pessoas, com pressa, tentando só pegar e fazer as coisas com os dados que eles queriam acesso. Eles foram basicamente saltar através de aros tentando acessar os dados apenas que levam à interface projeta degradar rapidamente.

Há algo vagamente parecido com encapsulamento ainda apenas devido à forma como o sistema está organizado desde há muitas vezes apenas um sistema de modificação de um determinado tipo de componentes (dois em alguns casos excepcionais). Mas eles não possuem esses dados, eles não fornecem funções para recuperar esses dados. Os sistemas não conversam entre si. Todos eles operam através da base de dados central ECS (que é a única dependência que tem de ser injectado em todos estes sistemas).

Flexibilidade e extensibilidade

Esta é já amplamente discutido em recursos externos sobre os sistemas entidade componente, mas eles são extremamente flexíveis na adaptação às radicalmente novas idéias de design em hindsight, quebra-conceito queridos até mesmo como uma sugestão para uma criatura que é um mamífero, inseto e planta que as folhas de couve sob a luz solar de uma vez.

Uma das razões é porque não existem abstrações centrais para quebrar. Você introduzir alguns novos componentes, se você precisar de mais dados para esta ou apenas criar uma entidade que cordas juntos os componentes necessários para uma planta, mamífero, e insetos. Os sistemas projetados para componentes processo de insetos, mamíferos e plantas, em seguida, automaticamente pegá-lo e você pode obter o comportamento desejado sem mudar nada além de adicionar uma linha de código para instanciar uma entidade com uma nova combinação de componentes. Quando você precisa de funcionalidade completamente nova, que você acabou de adicionar um novo sistema ou modificar um já existente.

O que eu não encontrei discutido tanto em outros lugares é o quanto esta manutenção flexibiliza mesmo em cenários quando não há alterações de design de quebra de conceito que não conseguiram antecipar. Mesmo ignorando a flexibilidade da ECS, pode coisas realmente simplificar quando sua base de código atinge uma certa escala.

Ligar objetos em dados

Em uma base de código OOP-pesada anterior, em que Vi a dificuldade de manter uma base de código mais perto do primeiro gráfico acima, a quantidade de código necessário explodida porque o Car analógico neste diagrama:

enter descrição da imagem aqui

... tinha que ser construído como um subtipo completamente separado (classe) implementar várias interfaces. Então, nós tivemos um número explosivo de objetos no sistema: um objeto separado para as luzes de ponto de luzes direcionais, um objeto separado para uma câmera olho de peixe de outro, etc. Tivemos milhares de objetos implementando algumas dezenas de interfaces abstratas em infinitas combinações.

Quando eu comparei com ECS, que exigia apenas centenas e nós fomos capazes de fazer exatamente as mesmas coisas antes de usar uma pequena fração do código, porque isso virou a entidade Car analógica em algo que não requer sua classe. Ele se transforma em uma simples coleção de dados de componente como uma instância generalizada de apenas um tipo Entity.

OOP Alternativas

Portanto, há casos como este, onde OOP aplicados em excesso no nível mais amplo do projeto pode começar a manutenção realmente degrade. No mais ampla visão panorâmica de seu sistema, ele pode ajudar a achatá-lo e não tentar modelar tão "profunda" com objetos interagindo com objetos que interagem com objetos, no entanto abstratamente.

Na comparação entre os dois sistemas em que trabalhei no passado e agora, o novo tem mais recursos, mas leva centenas de milhares de LOC. O ex necessário mais de 20 milhões LOC. Claro que não é a comparação mais justa desde o anterior tinha um enorme legado, mas se você tomar uma fatia dos dois sistemas que são funcionalmente muito igual sem a bagagem legado (pelo menos tão perto de igualar, como poderíamos obter), o ECS leva uma pequena fração do código para fazer a mesma coisa, e em parte porque reduz drasticamente o número de classes existem no sistema, transformando-as em coleções (entidades) de dados em bruto (componentes) com sistemas robustos para processá-los em vez de um barco cheio de objetos / médias pequenas.

Existem cenários em que um paradigma realmente non-OOP é realmente um melhor escolha para uma solução em larga escala? Ou isso é inédito destes dias?

Está longe de ser inédito. O sistema que estou descrevendo acima, por exemplo, é amplamente utilizado em jogos. É muito raro na minha área (a maioria das arquiteturas em meu campo são COM-like com interfaces puros, e esse é o tipo de arquitetura em que trabalhei no passado), mas eu descobri que espiando por cima com o que os jogadores estão fazendo quando projetar uma arquitetura feita aworld de diferença em ser capaz de criar algo que ainda permanece muito compreensível para ele cresce e cresce.

Dito isto, algumas pessoas consideram ECS para ser um tipo de programação orientada a objetos por conta própria. Se assim for, não se assemelha OOP de um tipo a maioria de nós pensaria, já que dados (componentes e entidades a compô-los) e funcionalidade (sistemas) são separados. Ela exige abandonar encapsulamento ao nível do sistema amplo que é muitas vezes considerado um dos aspectos mais fundamentais da OOP.

de Alto Nível de Codificação

Mas parece-me que, geralmente, os pedaços de soluções de nível superior são quase sempre juntos de uma forma OOP.

Se você pode juntar uma aplicação com código de nível muito alto, então ele tende a ser bastante pequena ou média na escala, tanto quanto o código de sua equipe tem de manter e, provavelmente, pode ser montado de forma muito eficaz utilizando OOP.

No meu campo de VFX, muitas vezes temos que fazer coisas que são relativamente de baixo nível como raytracing, processamento de imagem, malha processamento, dinâmica de fluidos, etc, e não pode simplesmente peça-los juntos a partir de produtos de terceiros, uma vez que' está realmente competindo mais em termos do que podemos fazer no nível baixo (usuários se mais animado com tecnologia de ponta, tornando a produção competitiva melhorias do que, digamos, uma interface gráfica mais agradável). Portanto, não pode haver lotes e lotes de código variando de muito baralhar baixo nível de bits e bytes para código de alto nível que scripters escrever através de linguagens de script embutidos.

Interweb de Comunicação

Mas chega um ponto com uma escala grande o suficiente com qualquer tipo de aplicação, de alto nível ou de baixo nível ou um combo, que gira em torno de um estado de aplicação central muito complexo onde eu encontrei ele não é mais útil tentar para encapsular tudo em objetos. Fazer isso tende a complexidade multiplicam e a dificuldade de raciocinar sobre o que acontece devido à quantidade multiplicada de interação que acontece entre tudo. Já não se torna tão fácil de razão sobre milhares de ecossistemas falando uns aos outros se não houver um ponto de ruptura em uma escala grande o suficiente onde paramos de modelagem de cada coisa como ecossistemas encapsuladas que têm de falar uns com os outros. Mesmo que cada um é individualmente simples, tudo tomada como um todo pode começar a mais de oprimir a mente, e muitas vezes temos que tomar um monte de que para fazer alterações e adicionar novas funcionalidades e coisas de depuração e assim por diante, se você tentar girar o desenho de um sistema de grande escala inteira apenas em torno de princípios OOP. Pode ajudar a quebrar livre de encapsulamento em alguma escala, pelo menos, alguns domínios.

Nesse ponto não é necessariamente assim mais útil para, digamos, ter uma encapsular sistema de física seus próprios dados (caso contrário, muitas coisas poderiam querer falar com ele e recuperar esses dados, bem como inicializá-lo com os dados de entrada apropriado), e é aí que eu encontrei esta alternativa através ECS tão útil, uma vez que transforma o sistema de física analógica, e todos esses sistemas robustos, em um "transformador de banco de dados central" ou um "leitor de banco de dados central que saídas de algo novo", que agora pode ser sobre alheio entre si. Cada sistema, em seguida, começa a assemelhar-se mais como um processo numa tubagem plana de um objecto que forma um nó num gráfico muito complexa de comunicação.

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