A OOP está se tornando mais fácil ou mais difícil? [fechadas]

36

Quando os conceitos de programação orientada a objetos foram introduzidos aos programadores anos atrás, parece interessante e a programação era mais limpa. OOP foi assim

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);

Isso foi mais fácil de entender com o nome autodescritivo.

Mas agora OOP, com padrões como Data Transfer Objects, Value Objects, Repository, Dependency Injection, etc., tornou-se mais complexo. Para alcançar o acima, você pode ter que criar várias classes (por exemplo, resumo, fábrica, DAO etc) e implementar várias interfaces

Nota: não sou contra as práticas recomendadas que facilitam a colaboração, o teste e a integração

    
por tunmise fasipe 10.06.2012 / 16:17
fonte

8 respostas

35

OOP em si não mudou muito desde a sua criação. Alguns novos ângulos foram explorados, mas os princípios centrais ainda são os mesmos. Se alguma coisa, o conhecimento coletivo reunido ao longo dos anos torna a vida do programador mais fácil do que difícil. Padrões de design não são um obstáculo; eles fornecem uma caixa de ferramentas de soluções para problemas padrão, destilados de anos e anos de experiência.

Então, por que você percebe a OOP hoje como mais complexa do que quando começou a usá-la?

Um motivo pode ser que o código ao qual você está sendo exposto se torne mais complexo - não porque a OOP se tornou mais complexa, mas porque você avançou na escada de aprendizado e consegue ler bases de código maiores e mais complexas.

Outra razão pode ser que, embora o paradigma da complexidade não tenha mudado, o tamanho e a complexidade de um projeto de software médio podem muito bem ter. Com o poder de processamento disponível em telefones celulares de nível de cliente que teriam sido o sonho molhado de um desenvolvedor em um servidor há menos de duas décadas, o público em geral esperava apenas GUIs animados e até mesmo o aplicativo descartável mais barato. Como o PC de mesa é mais poderoso do que um "supercomputador" dos anos 80, é natural que a barra tenha sido levantada desde os primórdios de Smalltalk e C ++.

E há o fato de que, em aplicativos modernos, a simultaneidade e o paralelismo são a norma, e não a exceção, e os aplicativos frequentemente precisam se comunicar entre diferentes máquinas, gerando e analisando todo um zoológico de protocolos. Embora o OOP seja excelente como um paradigma organizacional, ele tem suas limitações, assim como qualquer outro paradigma: por exemplo, ele não fornece muita abstração para simultaneidade (a maioria das implementações é mais ou menos uma reflexão tardia ou é totalmente terceirizada para bibliotecas) e não é a melhor abordagem possível para criar analisadores e transformar dados. A programação moderna frequentemente se depara com as limitações do paradigma OOP, e os padrões de design só podem levá-lo até certo ponto. (Pessoalmente, considero o fato de que precisamos de padrões de projeto um sinal disso - se o paradigma fornecesse essas soluções prontas para uso, seria mais expressivo para esses problemas, e as soluções padrão seriam óbvias. nenhum padrão de design para descrever a herança de método, porque é uma característica central da OOP, mas há um padrão de fábrica, porque a OOP não fornece uma maneira natural óbvia de construir objetos de maneira polimórfica e transparente.

Por causa disso, a maioria das linguagens OOP modernas incorporam recursos de outros paradigmas, o que os torna mais expressivos e mais poderosos, mas também mais complexos. C # é o principal exemplo para isso: tem óbvias raízes de OOP, mas recursos como delegados, eventos, inferência de tipos, tipos de dados variantes, atributos, funções anônimas, expressões lambda, genéricos, etc., se originam de outros paradigmas, principalmente Programação Funcional .

    
por 10.06.2012 / 17:35
fonte
17

Não, está se tornando mais engenhoso. E você está certo - no bate-papo do SO C ++ nós frequentemente brincamos sobre os AbstractSingletonFactoryProxyBeanAdaptterManagers que vemos no código Java.

Mas um bom código não exibe essa propriedade. Em bom código, você ainda pode dizer

std::stack<int> s;
s.push(5);
s.pop();
    
por 10.06.2012 / 16:27
fonte
10

Eu diria que os problemas com "complexidade" que você menciona não tem nada a ver com OOP. Tem mais a ver com separar as preocupações.

Há muitos anos, trabalhei em um sistema no qual a classe de domínio tinha a responsabilidade de se carregar do banco de dados, por exemplo

var userId = Request.QueryString["UserID"].ToInt();
var user = new User(userId);
user.Name = ...;
...
user.Save();

Este é um código muito claro. Não há problema em entender isso. O problema, no entanto, seria na unidade testando o código. Ou seja, como eu testaria a unidade da classe User sem precisar carregar uma do banco de dados? E como eu testaria essa solicitação da Web manipulando o código sem ter acesso ao banco de dados? Simplesmente não é possível.

É por isso que temos um padrão como um repositório, para separar a responsabilidade de manipular a lógica de domínio de um usuário da funcionalidade de realmente carregar e salvar um em um armazenamento de dados. O IOC ajuda a reduzir o acoplamento, também tornando o código mais testável, etc.

Então, se voltarmos ao exemplo que você escreve, o que você faria com o estoque depois de criá-lo? Salve no banco de dados

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);
this.StockRepository.Add(stock);

Lá, pronto! Não há movimento na progressão da POO que sugira que seja mais difícil. Infelizmente, se você escolher usar um mapeador OR para o código de acesso a dados, poderá encontrar o problema de o mapeador do OR estar colocando restrições sobre como você pode escrever seu sistema. Mas isso é outro assunto.

Se você é novo nesses padrões, talvez seja necessário aprender um novo estilo de programação. Mas esse estilo de programação não é mais difícil do que a programação OOP da velha escola.

    
por 10.06.2012 / 16:56
fonte
4

Nem Nossos problemas não mudaram realmente; a barra de código aceitável foi levantada.

To achieve the above you may have to create several classes (e.g. abstract, factory, DAO etc) and Implement several interfaces

Você não tem para fazer isso. Mas se você não fizer isso, os problemas surgirão; problemas que sempre estiveram lá. Agora, porém, os programadores têm experiência suficiente para identificar esses problemas e fornecer mecanismos para aliviá-los (se necessário). Aprendemos mais sobre isso e desenvolvemos soluções melhores (veja - as visões dos programadores sobre o singleton, por exemplo).

Mas você também tem que perceber que a introdução de programadores para OO (ou qualquer coisa para esse assunto) tenderá a encobrir as circunstâncias excepcionais. É simplesmente mais fácil explicar o caminho feliz e preocupar-se com o descanso, uma vez que os iniciantes têm isso. Não há bala de prata; Então, sim, eu suponho que as coisas sempre parecem mais difíceis quando essa ilusão idílica é quebrada ...

    
por 11.06.2012 / 04:12
fonte
3

Os exemplos de "introdução a OO" são muito mais simples que uma aplicação do mundo real. Você só precisa de uma aula para alcançar o que foi dito acima. O problema é que não faz muito. Alguns padrões de design tentam se aproximar (como o ActiveRecord.) Mas, no final das contas, qualquer exemplo que não seja trivial terá mais de uma classe; tudo bem.

    
por 10.06.2012 / 16:25
fonte
3

As linguagens de programação que usam o OO hoje estão tentando atender a requisitos e ambientes complexos que continuam mudando. O OO permite que seus adotantes ocultem diversos níveis de complexidade (entre outros recursos) para que o código se torne mais claro e mais fácil de construir e entender. No entanto, esse recurso não está sempre fora da caixa. No seu exemplo, o OO permitiu-lhe esconder alguns detalhes de mim, fornecendo um método para gerenciar itens em uma coleção e pode até mesmo persistir usando o método "AddItem". Gastar esforço para ocultar a complexidade pode resultar em uma estrutura fácil de usar e reutilizável que torna a vida mais simples. Por exemplo, muitas implementações de ORM permitem que você se comunique com bancos de dados sem que o programador grave os detalhes do SQL. Isso é realmente poderoso e simplifica o desenvolvedor.

Os padrões aos quais você se refere são apenas isso. Eles deveriam tornar sua vida mais fácil. Mas cabe a você adotá-las e ajustá-las. O fato de que mais trabalho é necessário é apenas porque você ganha mais benefícios. É como pagar mais por uma Ferrari. Se você quiser os extras que você paga por eles. Portanto, se você decidir criar uma solução N-Tier dimensionável que possa ser executada em vários servidores e diferentes bancos de dados de back-end, haverá um custo para isso. Se o seu aplicativo não exigir essa complexidade, ignore as peças extras e recorra à solução mais simples que cubra sua necessidade (KISS & YAGNI).

Então, para finalizar, eu não acho que a OOP como um conceito em si esteja ficando mais complexa, nós, os usuários da OOP temos a opção de usá-la de maneiras diferentes, e isso é uma coisa boa.

    
por 10.06.2012 / 16:53
fonte
3

Resposta curta : Sim, porque você lida com problemas mais difíceis.

Resposta Longa (strongmente tendenciosa) : Para mim, os padrões de design geralmente indicam que algum paradigma tem problemas em determinada área. Os padrões OOP lidam com problemas de OOP (no nível inferior, os padrões Java lidam com problemas de Java), os padrões FP lidam com problemas de FP, etc.

Durante a programação, você pode ter diferentes prioridades. Você pode querer ter um programa correto, você pode querer ter tempo de comercialização curto, programa mais rápido possível, manutenção a longo prazo ou manutenção instantânea por uma nova contratação. Dependendo do bushiness você está em você terá muito diferente - se você está programando controlador de usina você quer fazer certo primeiro tempo e não bugfix toda vez agora e então ("A fusão ocorre toda vez que você pressiona Ctrl + Alt + Del ? "). Se você estiver no HPC, a lógica pode ser relativamente simples, mas você quer executá-la o mais rápido possível, etc. Além disso, alguns paradigmas se encaixam melhor em certos problemas (como programação lógica e AI, dados e bancos de dados relacionais).

OOP é de certa forma 'muito bom' em casos simples e é uma história de "modelagem ao vivo real". Por exemplo, no primeiro livro sobre OOP eu li que havia classes Person , Employee e Manager com is-a relacionamento. Até aí tudo bem, mas e se o funcionário for promovido a gerente?

Por outro lado, outros paradigmas têm lições mais difíceis na primeira vez - por exemplo, FP com variáveis imutáveis (o engraçado é que as pessoas que tiveram experiência com programação muitas vezes acham mais difícil aprender do que aquelas para quem é a primeira língua). em última análise, eles não são mais difíceis do que o OOP. Testar funções puras é trivial e em Haskell / Scala / ... você tem ferramentas que geram testes para você.

PS. Sim - a resposta é tendenciosa contra a OOP e eu admito que, em certa medida, ela está 'em reação' à OOP. OOP tem seus usos, mas não é a única solução definitiva na minha opinião.

PPS. Sim - use padrões de design - eles tornam a programação OOP mais simples.

PPPS. Eu usei OOP como sinônimo de programação imperativa OOP.

    
por 10.06.2012 / 20:34
fonte
2

Acho que é mais um caso de documentos e exemplos se tornando mais realistas.

Os primeiros livros de OOP (particularmente os primeiros livros de Java) apresentaram uma visão absurdamente simplificada da programação de aplicativos. O exemplo "Dedicar uma conta bancária com um programa Java de 10 linhas" sempre foi particularmente irritante, pois vi exemplos da vida real dessa tarefa simples sendo executados em 6000 linhas de código COBOL (e a tentativa de substituição do Java em 3500 linhas antes de ser abandonada como inviável!).

Felizmente, os livros OO tendem a reconhecer as complexidades da vida real e fornecem exemplos úteis de como lidar com eles.

Mas se você quiser ver como executar uma conta bancária em apenas 15 linhas de código a programação funcional é o seu parceiro

    
por 11.06.2012 / 06:53
fonte