Pergunta

Recentemente, tive um debate com um colega que não é fã de OOP. O que chamou minha atenção foi o que ele disse:

"Qual é o sentido de fazer minha codificação em objetos? Se for reutilizada, então eu posso apenas criar uma biblioteca e chamar quaisquer funções necessárias para qualquer tarefa que esteja à mão. Preciso desses conceitos de polimorfismo, herança, interfaces, padrões ou qualquer outra coisa? "

Estamos em uma pequena empresa desenvolvendo pequenos projetos para sites de comércio eletrônico e imóveis.

Como posso aproveitar o OOP em uma configuração "todos os dias do mundo real"? Ou o OOP realmente destinado a resolver problemas complexos e não destinada ao desenvolvimento "cotidiano"?

Foi útil?

Solução

As coisas boas sobre o OOP vêm de vincular um conjunto de dados a um conjunto de comportamentos.

Portanto, se você precisar fazer muitas operações relacionadas em um conjunto de dados relacionado, poderá escrever muitas funções que operam em uma estrutura ou pode usar um objeto.

Os objetos fornecem alguma ajuda de reutilização de código na forma de herança.

IME, é mais fácil trabalhar com um objeto com um conjunto conhecido de atributos e métodos que é manter um conjunto de estruturas complexas e as funções que operam neles.

Algumas pessoas continuarão sobre herança e polimorfismo. São valiosos, mas o valor real no OOP (na minha opinião) vem da boa maneira que ele encapsula e associa dados a comportamentos.

Você deve usar OOP em seus projetos? Isso depende de quão bem seu idioma suporta OOP. Isso depende dos tipos de problemas que você precisa resolver.

Mas, se você estiver fazendo sites pequenos, ainda está falando sobre complexidade suficiente para que eu usaria o design OOP, dado o suporte adequado no idioma de desenvolvimento.

Outras dicas

Minha visão pessoal: contexto

Ao programar em OOP, você tem uma maior consciência do contexto. Ajuda você a organizar o código de tal maneira que é mais fácil de entender, porque o mundo real também é orientado a objetos.

Mais do que conseguir algo apenas para trabalhar - o ponto do seu amigo, um design OO bem projetado é mais fácil de entender, seguir, expandir, estender e implementar. É muito mais fácil, por exemplo, delegar o trabalho que categoricamente é semelhante ou de manter dados que devem permanecer juntos (sim, mesmo uma estrutura C é um objeto).

Bem, tenho certeza de que muitas pessoas darão muito mais respostas academicamente corretamente, mas aqui está minha opinião sobre algumas das vantagens mais valiosas:

  • OOP permite um melhor encapsulamento
  • OOP permite que o programador pense em termos mais lógicos, facilitando o design e o entendimento (se bem projetado)
  • OOP é um economizador de tempo. Por exemplo, observe as coisas que você pode fazer com um objeto C ++ String, vetores, etc. Toda essa funcionalidade (e muito mais) vem para "GRATUITAMENTE". Agora, esses são realmente recursos das bibliotecas de classes e não opa em si, mas quase todas as implementações de OOP vêm com bibliotecas de classe agradáveis. Você pode implementar tudo isso em C (ou a maioria)? Claro. Mas por que escrever você mesmo?

Veja o uso de padrões de design e você verá a utilidade do OOP. Não se trata apenas de encapsulamento e reutilização, mas extensibilidade e manutenção. São as interfaces que tornam as coisas poderosas.

Alguns exemplos:

  • Implementar um fluxo (padrão de decorador) sem objetos é difícil

  • Adicionar uma nova operação a um sistema existente, como um novo tipo de criptografia (padrão de estratégia), pode ser difícil sem objetos.

  • Veja a maneira como o PostgreSQL é implementado versus a maneira como seu livro de banco de dados diz que um banco de dados deve ser implementado e você verá uma grande diferença. O livro sugerirá objetos de nó para cada operador. O Postgres usa inúmeras tabelas e macros para tentar imitar esses nós. É muito menos bonito e muito mais difícil de estender por causa disso.

A lista continua.

O poder da maioria das linguagens de programação está nas abstrações que eles disponibilizam. A programação orientada a objetos fornece um sistema muito poderoso de abstrações da maneira como permite gerenciar relacionamentos entre idéias ou ações relacionadas.

Considere a tarefa de calcular áreas para uma coleção arbitrária e expandida de formas. Qualquer programador pode escrever rapidamente funções para a área de um círculo, quadrado, triângulo, ect. e armazene -os em uma biblioteca. A dificuldade ocorre ao tentar escrever um programa que identifique e calcule a área de uma forma arbitrária. Cada vez que você adiciona um novo tipo de forma, por exemplo, um Pentágono, você precisaria atualizar e estender algo como um IF ou CASE Estrutura para permitir que seu programa identifique a nova forma e chame a rotina de área correta da sua "Biblioteca de Funções". Depois de um tempo, os custos de manutenção associados a essa abordagem começam a se acumular.

Com a programação orientada a objetos, muito disso vem de graça-basta definir uma classe de forma que contém um método de área. Em seguida, não importa realmente com que forma específica você está lidando no tempo de execução, basta fazer de cada figura geométrica um objeto que herda da forma e chamar o método da área. O paradigma orientado a objeto lida com os detalhes de se neste momento, com essa entrada do usuário, precisamos calcular a área de um círculo, triângulo, quadrado, Pentágono ou a opção de elipse que foi adicionada apenas meio minuto atrás.

E se você decidisse mudar a interface por trás da maneira como a função da área foi chamada? Com a programação orientada a objetos, você apenas atualizaria a classe Shape e as alterações se propagam automaticamente para todas as entidades que herdam dessa classe. Com um sistema não orientado a objetos, você estaria enfrentando a tarefa de passar pela sua "biblioteca de funções" e atualizar cada interface individual.

Em resumo, a programação orientada a objetos fornece uma forma poderosa de abstração que pode economizar tempo e esforço, eliminando a repetição em seu código e simplificando extensões e manutenção.

Todos os paradigmas de programação têm o mesmo objetivo: ocultar a complexidade desnecessária.

Alguns problemas são facilmente resolvidos com um paradigma imperativo, como seu amigo usa. Outros problemas são facilmente resolvidos com um paradigma orientado a objetos. Existem muitos outros paradigmas. Os principais (programação lógica, programação funcional e programação imperativa) são equivalentes entre si; A programação orientada a objetos é geralmente considerada uma extensão para a programação imperativa.

A programação orientada a objetos é melhor usada quando o programador está modelando itens semelhantes, mas não iguais. Um paradigma imperativo colocaria os diferentes tipos de modelos em uma função. Um paradigma orientado a objetos separa os diferentes tipos de modelos em diferentes métodos em objetos relacionados.

Seu colega parece estar preso em um paradigma. Boa sorte.

Por volta de 1994, eu estava tentando entender o OOP e o C ++ ao mesmo tempo, e fiquei frustrado, mesmo que eu pudesse entender em princípio qual era o valor da OOP. Eu estava tão acostumado a poder mexer com o estado de qualquer parte da aplicação de outros idiomas (principalmente idiomas básicos, montagens e familiares) que parecia que eu estava desistindo da produtividade em favor de alguma abstração acadêmica. Infelizmente, meus primeiros encontros com estruturas OO como o MFC tornaram mais fácil hackear, mas não necessariamente forneceram muito em termos de iluminação.

Foi somente através de uma combinação de persistência, exposição a maneiras alternativas (não C ++) de lidar com objetos e uma análise cuidadosa do código OO que ambos 1) funcionaram e 2) leem de forma mais coerente e intuitivamente do que o código processual equivalente que iniciei para realmente conseguir. E 15 anos depois, estou regularmente surpreso com as novas (para mim) descobertas de soluções OO inteligentes, mas impressionantemente simples, que não consigo imaginar fazer tão bem em uma abordagem processual.

Eu tenho passado pelo mesmo conjunto de lutas tentando entender o paradigma de programação funcional nos últimos dois anos. Parafraseando Paul Graham, quando você está olhando para o continuum de poder, você vê tudo o que está faltando. Quando você procura o continuum de poder, não vê o poder, apenas vê estranheza.

Eu acho que, para se comprometer a fazer algo de uma maneira diferente, você precisa 1) ver alguém obviamente sendo mais produtivo com construções mais poderosas e 2) suspender a descrença quando você se encontrar atingindo uma parede. Provavelmente ajuda a ter um mentor que é pelo menos um pouquinho mais adiante na compreensão do novo paradigma também.

Salvo o bom senso necessário para suspender a descrença, se você deseja que alguém rapidamente se destaque no valor de um modelo OO, acho que você poderia fazer muito pior do que pedir a alguém que passe uma semana com o livro de programadores pragmáticos sobre trilhos. Infelizmente, deixa de fora muitos detalhes de como a mágica funciona, mas é uma boa introdução ao poder de um sistema de abstrações OO. Se, depois de trabalhar nesse livro, seu colega ainda não vê o valor do OO por algum motivo, ele pode ser um caso sem esperança. Mas se eles estão dispostos a gastar um pouco de tempo trabalhando com uma abordagem que tem um design de OO fortemente opinativo que funciona e os obtém de 0 a 60 muito mais rápido do que fazer a mesma coisa em uma linguagem processual, pode haver apenas esperança. Eu acho que isso é verdade mesmo que seu trabalho não envolva o desenvolvimento da Web.

Não tenho tanta certeza de que a criação do "mundo real" seria tanto um ponto de venda quanto uma estrutura de trabalho para escrever bons aplicativos, porque acontece que, especialmente em idiomas estaticamente digitados como C# e Java, modelando o mundo real geralmente requer abstrações tortuosas. Você pode ver um exemplo concreto da dificuldade de modelar o mundo real olhando milhares de pessoas lutando para modelar algo tão ostensivamente simples quanto a abstração geométrica de "Shape" (Shape, Ellipse, Circle).

Para mim, o poder da OOP não se mostra até você começar a falar sobre herança e polimorfismo.

Se o argumento de alguém para OOP repousa o conceito de encapsulamento e abstração, bem, esse não é um argumento muito convincente para mim. Eu posso escrever uma enorme biblioteca e apenas documentar as interfaces que quero que o usuário esteja ciente, ou posso confiar em construções no nível de idioma, como pacotes na ADA para tornar os campos privados e expor apenas o que eu quero que eu queira expor.

No entanto, a verdadeira vantagem ocorre quando escrevi código em uma hierarquia genérica, para que possa ser reutilizada posteriormente, de modo que as mesmas interfaces exatas de código sejam usadas para funcionalidade diferente para obter o mesmo resultado.

Por que isso é útil? Porque eu posso ficar nos ombros dos gigantes para realizar minha tarefa atual. A idéia é que eu possa ferver as partes de um problema nas partes mais básicas, os objetos que compõem os objetos que compõem ... os objetos que compõem o projeto. Ao usar uma classe que define o comportamento muito bem no caso geral, posso usar o mesmo código comprovado para criar uma versão mais específica da mesma coisa e, em seguida, uma versão mais específica da mesma coisa, e depois ainda mais específica versão da mesma coisa. A chave é que cada uma dessas entidades tem a semelhança que já foi codificada e testada, e não há necessidade de reimplentá -la novamente mais tarde. Se eu não usar a herança para isso, acabo reimplementando a funcionalidade comum ou vinculando explicitamente meu novo código contra o código antigo, que fornece um cenário para eu introduzir bugs de fluxo de controle.

O polimorfismo é muito útil nos casos em que eu preciso obter uma determinada funcionalidade de um objeto, mas também é necessária a mesma funcionalidade de tipos semelhantes, mas exclusivos. Por exemplo, no QT, existe a idéia de inserir itens em um modelo para que os dados possam ser exibidos e você possa manter facilmente metadados para esse objeto. Sem o polimorfismo, eu precisaria me incomodar com muito mais detalhes do que atualmente (ou seja, precisaria implementar as mesmas interfaces de código que conduzem a mesma lógica de negócios que o item que se destinava originalmente a entrar no modelo). Como a classe base do meu objeto ligado a dados interage nativamente com o modelo, posso inserir metadados nesse modelo sem problemas. Recebo o que preciso do objeto sem preocupação com o que o modelo precisa, e o modelo obtém o que precisa sem se preocupar com o que eu adicionei à classe.

Peça ao seu amigo para visualizar algum Objeto em seu próprio quarto, casa ou cidade ... e se ele puder contar a um único objeto que um sistema em si e é capaz de fazer um trabalho significativo.

Coisas como um botão não estão fazendo algo sozinho - são necessários muitos objetos para fazer uma ligação.
Da mesma forma, um motor de carro é feito de eixo de manivela, pistões, velas de ignição. Os conceitos de opa evoluíram de nossa percepção em processos naturais ou coisas em nossas vidas.

O livro "Inside Com" conta o objetivo do COM, levando a analogia de um jogo de infância de identificar animais, fazendo perguntas.

O design supera a tecnologia e a metodologia. Bons projetos tendem a incorporar diretores universais de gerenciamento de complexidade, como a lei do Demeter, que está no centro do que os recursos da linguagem OO se esforçam para codificar.

O bom design não depende do uso de recursos de linguagem específica do OO, embora normalmente seja do melhor interesse para usá -los.

Não apenas faz

  • Programação mais fácil / mais sustentável na situação atual para outras pessoas (e você)
  • Já está permitindo operações mais fáceis de banco de dados (criar, atualizar, excluir).

Você pode encontrar mais informações sobre isso: - Java: Hibernate - Dot Net: Entity Framework

Veja até como o LINQ (Visual Studio) pode facilitar sua vida de programação.

  • Além disso, você pode começar a usar padrões de design para resolver problemas da vida real (os padrões de design são sobre OO)

Talvez seja até divertido demonstrar com uma pequena demonstração:

  • Digamos que você precise armazenar funcionários, contas, membros, livros de um arquivo de texto de maneira semelhante.

.Ps. Eu tentei escrever de uma maneira pseudo :)

o jeito OO

Código que você chama: io.file.save (objectSscollection.ourfunctionForsAved ())

Classe ObjectScollection

function OurFunctionForSaving () como string

String _Objects

   for each _Object in objectsCollection
         Objects &= _Object & "-"
   end for

Retornar _Objects End Method

Caminho não OO

Acho que não vou escrever código não OO. Mas pense nisso :)

Agora digamos

Da maneira OO. A classe acima é a classe pai de todos os métodos para salvar os livros, funcionários, membros, contas, ... o que acontece se queremos mudar a maneira de economizar para um arquivo de texto? Por exemplo, para torná -lo compacto com um padrão atual (.CVS).

E digamos que gostaríamos de adicionar uma função de carga, quanto código você precisa escrever? Na via, você só precisa adicionar um novo sub-método que pode dividir todos os dados em parâmetros (isso acontece uma vez).

Deixe seu colega pensar sobre isso :)

Nos domínios onde o estado e o comportamento estão pouco alinhados, a orientação de objetos reduz a densidade geral de dependência (ou seja, complexidade) dentro desses domínios, o que torna os sistemas resultantes menos quebradiços.

Isso é porque o essência A orientação a objetos é baseada no fato de que, organizacionalmente, não se espalha entre estado e comportamento, tratando uniformemente como "recursos". Objetos são apenas conjuntos de recursos que estão confusos para minimizar No geral dependência.

Em outros domínios, a orientação de objetos não é a melhor abordagem. Existem diferentes paradigmas de idiomas para diferentes problemas. Desenvolvedores experientes sabem disso e estão dispostos a usar qualquer idioma mais próximo do domínio.

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