Relação entre orientação a objetos e algoritmos

9

Enquanto leio alguns livros didáticos de algoritmos, eles estão cheios de procedimentos inteligentes para alguns problemas (classificação, caminho mais curto) ou alguns métodos gerais (algoritmos recursivos, divisão e conquista, programação dinâmica ...). Encontrei poucos traços de programação orientada a objetos lá; (Por que eles são mais orientados a procedimentos?).

Então eu estava pensando:

  • Qual é a relação entre algoritmos e OOP? Eles são dois tópicos independentes?
  • Existem alguns problemas que só podem ser apresentados e resolvidos pelo OOP?
  • Como o OOP pode ajudar os algoritmos? Ou em que direção isso pode afetá-lo?
Ahmad
fonte
4
Não é uma duplicata, mas sim programadores
Doc Brown
@DocBrown Obrigado, que foi muito útil, mas aqui podemos considerar alguns conceitos em torno da OO como herança, polimorfismo ...
Ahmad
11
"Por que o livro didático de algoritmos é mais orientado a procedimentos?" Java também é orientado a procedimentos. Java é uma linguagem procedural orientada a objetos.
Pieter B
11
@gnat Modifiquei minha pergunta, não sei se essa explicação foi necessária ou boa ou não. No entanto, admito que a pergunta feita pelo Doc Brown possua mais respostas relacionadas às minhas preocupações.
Ahmad

Respostas:

10

Primeiro, vamos definir o que queremos dizer com OOP. Com OOP, quero dizer principalmente:

  • Encapsulamento e ocultação de detalhes em sala de aula.
  • Polimorfismo de comportamento por herança e métodos virtuais.

Agora respondendo à sua questão:

Qual é a relação entre algoritmos e OOP? Eles são dois tópicos independentes?

Sim.

Existem alguns problemas que somente podem ser apresentados e resolvidos pelo OOP?

Não. OOP primário oferece conveniência e capacidade de raciocinar sobre código para programador. Não aumenta seu poder expressivo.

Como OOP pode ajudar algoritmos? Ou em que direção isso pode afetá-lo?

Como eu disse acima. Os dois pontos que descrevi como POO se aplicam aqui. Ser capaz de ocultar detalhes de algoritmos e suas estruturas de dados pode ajudar a raciocinar sobre tudo. Muitos algoritmos contêm detalhes com os quais você não quer que o usuário mexa com ele. Esconder esses detalhes ajuda muito.

A capacidade de ter um comportamento polimórfico também é excelente. Listé definido como sendo capaz de adicionar / remover / limpar os itens em qualquer lugar da coleção. Mas pode ser implementado como uma matriz redimensionável, com link duplo ou único, etc. Ter uma API única para várias implementações pode ajudar a reutilizar.

Por que o livro didático de algoritmos é mais orientado a procedimentos?

Como eu disse, OOP não é necessário para implementar um algoritmo. Além disso, muitos algoritmos são antigos e criados quando o OOP ainda não era generalizado. Portanto, também pode ser uma coisa histórica.

Eufórico
fonte
11
Apesar da idade dos textos, você provavelmente não gostaria de turvar a água de um algoritmo com o OOP, apenas porque é moderno.
Gusdor 6/02/2015
15

Algoritmos e POO são dois termos díspares, que têm apenas em comum, que são termos de CS . Simplesmente - Um algoritmo é como uma receita culinária : para fazer x, você precisa dos seguintes ingredientes e faz o passo 1,2,3,4,5,6 ... então você tem sua refeição preparada.

Dito isto, parece natural que os algoritmos sejam descritos de maneira processual . Procedimental significa nada além de: primeiro faça x e depois faça y .

Um problema comum é: »Como classificar um conjunto de x ?«. Uma solução fácil de entender é bubble-sort:

  1. Itere o conjunto a partir do último elemento, desde que você não tenha atingido o primeiro elemento e durante a iteração
  2. Inicie uma segunda iteração desde o início até o elemento atual da primeira iteração e
  3. Compare o elemento atual de (2) com seu sucessor
  4. Se maior, troque de posição

Essa é a descrição algorítmica / verbal do bubblesort-algoritmo.

Aí vem uma implementação procedural / pseudocódigo

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

Essa foi fácil.

Como isso se relaciona com o OOP ? Você pode usar este algoritmo para tratar coleções (um objeto em si) de objetos :

Exemplo em Javascript (embora sem OO-Lingo limpo , mas com quase nenhum clichê e fácil de entender)

objects =[{"name":"Peter"}, {"name":"Paul"}, {"name":"Mary"}]

compareObjects=function(x,y){ return x.name>y.name };

sorted = objects.sort(compareObjects)

console.log(sorted)

Temos a) uma coleção objects, b) um método comum a essa coleção sortque contém / abstrai o algoritmo de classificação ec) nossos objetos Peter , Paul e Mary . A especificação para a classificação é encontrada aqui .

Qual é a relação entre algoritmos e OOP? Eles são dois tópicos independentes?

Pelo que foi dito, deve ficar claro, a resposta deve ser: sim, eles são independentes.

Como OOP pode ajudar algoritmos? Ou em que direção isso pode afetá-lo?

OOP é apenas um estilo de programação. Não pode ajudar de nenhum tipo. Caso contrário, um algoritmo pode ser implementado em uma linguagem OO para fazer algo com objetos (como mostrado)

Existem alguns problemas que somente podem ser apresentados e resolvidos pelo OOP?

Não consigo pensar em um (mas isso não significa que é impossível). Mas se você analisar o contrário: OOP é útil, se você deseja modelar alguns problemas e resolver com um algoritmo apropriado. Digamos que você tenha um registro de friendsque você poderia modelá-los como objectscom propertiese se você quiser um listdos friends ordenados de qualquer forma, você pode usar o exemplo de código de dado acima para fazer exatamente isso.

Por que o livro didático de algoritmos é mais orientado a procedimentos?

Como dito: é mais natural , pois processual é o caráter de algoritmos.

Thomas Junk
fonte
7
Esta resposta pressupõe que os algoritmos são naturalmente procedurais. Certamente alguns deles são, mas existem algoritmos funcionais. A razão pela qual os livros de algoritmos são processuais provavelmente tem mais a ver com o fato de estarem focados no desempenho e, portanto, cabe ao leitor se preocupar em impor abstrações e porque as linguagens imperativas são mais populares que as linguagens funcionais.
Doval
Eu acho que isso não está certo. Ao falar de linguagens de programação funcional , você está falando sobre a implementação , não sobre o próprio algoritmo. Tomemos, por exemplo, o quicksort wiki de Haskell.haskell.org/Introduction#Quicksort_in_Haskell Nós dois concordaríamos que essa é uma implementação funcional para o quicksort-algortihm. Mas se você descrever o que é feito, precisará recorrer a um modo de descrição prodecural . E a partir dessa descrição, você pode implementar uma implementação processual.
Thomas Junk
11
@ThomasJunk Você não precisa voltar ao modo processual de descrição, porque uma implementação funcional diz o que são as coisas , não uma sequência de etapas. Como você dará uma descrição seqüencial para uma computação pura e preguiçosa? Você não sabe antecipadamente quanto de uma expressão será avaliada, nem em que ordem suas subexpressões serão computadas.
D
2
Infelizmente, eu não tenho um diploma em CS, então não tenho um amplo conjunto de habilidades para provar o seguinte: mas acho que todo algoritmo pode ser descrito de uma maneira ou de outra. Portanto, não existe um algoritmo funcional puro genuíno. Não é isso, o que significa estar completo em turnê?
Thomas Junk
2
@Doval bem, já que o próprio Turing provou que o cálculo lambda e as máquinas de Turing são equivalentes; então, é óbvio que tudo o que você pode declarar de uma maneira funcional, é imperativo. Também é trivial converter computação lenta em forma imperativa - o compilador de Haskell faz isso o tempo todo ... No final, é apenas uma questão de preferência. Às vezes funcional é mais adequado, e às vezes imperativo, e outras vezes lógico é o melhor ...
AK_
5

você tem um problema.

O modelo do domínio de negócios descreve seu problema e os conceitos do domínio do problema com o qual você está lidando.

Algoritmos descrevem a maneira como você vai resolver seus problemas, conceitualmente; como será sua implementação; e como você lida com o seu problema depois de traduzi-lo em termos de "Ciência da computação".

O paradigma de programação , OOP, Funcional, Lógico, Procedimental ou mesmo Não Estruturado, descreve como você estruturará sua solução, que forma será adotada, quais conceitos de "Engenharia de Software" você empregará e quais " Teoria da Linguagem de Programação "você vai empregar.

Para simplificar, os algoritmos descrevem em geral sua solução para o problema ("É isso que eu vou fazer"). Enquanto o paradigma de programação lida com a sua implementação real ("É assim que eu vou fazer").

AK_
fonte
Observe que, de uma maneira possivelmente imperfeita, as linguagens declarativas visam reduzir ou eliminar a etapa "como". O objetivo deles é que você simplesmente diga "é isso que eu quero" (por exemplo, escrevendo equações de alto nível). Pense em uma consulta SQL típica: muito pouco dela é "algorítmica"; você simplesmente diz ao banco de dados o que deseja e depende de como ele lida com sua solicitação (dentro de certas limitações, é claro).
Andres F.
4

Algoritmos = conte a história " Como " (isto é, como manipular dados de entrada usando estruturas de dados a tempo de produzir os resultados desejados)

OOP = uma " Metodologia " facilitada pelas linguagens OO para escrever programas (= algoritmos + estruturas de dados) que oferecem segurança e abstração de memória

OOP é apenas um paradigma de implementação de algoritmos.

Boa analogia : filmes

Você pode gravar cenas usando um dublê ou não. O roteiro (algoritmo) não muda. As pessoas não devem ver nenhuma diferença no resultado final.

EDIT: você pode experimentar um MOOC de boa qualidade: https://www.coursera.org/course/algs4partI, que intercala os tópicos discutidos (especialmente a abordagem OOP) e fornece a essência do que você pede aqui.

Marcin Wachulski
fonte
Gostei muito da analogia do seu filme. Eu vou pedir emprestado esse no futuro.
Marc LaFleur
2

Alexander Stepanov é o criador original da C ++ Standard Template Library, (STL), que é a biblioteca de algoritmos fundamental para C ++. C ++ é uma linguagem de múltiplos paradigmas que inclui recursos "Orientados a objetos", mas Alexander Stepanov tem isso a dizer sobre Orientação a objetos:

http://www.stlport.org/resources/StepanovUSA.html

STL não é orientado a objetos. Eu acho que a orientação a objetos é quase tão falsa quanto a Inteligência Artificial. Ainda tenho que ver um pedaço interessante de código que vem dessas pessoas OO.

Acho OOP tecnicamente doentio. Ele tenta decompor o mundo em termos de interfaces que variam em um único tipo. Para lidar com os problemas reais, você precisa de álgebras com várias classes - famílias de interfaces que abrangem vários tipos. Acho POO filosoficamente doentio. Alega que tudo é um objeto. Mesmo que seja verdade, não é muito interessante - dizer que tudo é um objeto não está dizendo nada. Acho OOP metodologicamente errado. Começa com as aulas. É como se os matemáticos começassem com axiomas. Você não começa com axiomas - você começa com provas. Somente quando você encontrar várias provas relacionadas, poderá obter axiomas. Você termina com axiomas. O mesmo se aplica à programação: você precisa começar com algoritmos interessantes. Somente quando você os entende bem,

Passei anos tentando encontrar algum uso para herança e virtuais, antes de entender por que esse mecanismo era fundamentalmente falho e não deveria ser usado.

Stepanov expressou sua biblioteca de algoritmos não com objetos, mas com iteradores genéricos .

James Brock
fonte
Bem, ele está errado ... principalmente porque o STL é muito orientado a objetos ... Orientado a objetos no mais moderno desde o termo ...
AK_
11
@AK_ - Eu não acho que ele esteja errado. STL nem sequer é aproximadamente OO em qualquer sentido do termo. Você pode traduzir o STL diretamente em uma linguagem não OO que possua polimorfismo paramétrico (por exemplo, Haskell ou SML) sem precisar alterá-lo de maneira substancial.
Jules
2

Algoritmos descrevem o que o computador deve fazer. Estrutura descreve como o algoritmo é organizado [no código fonte]. OOP é um estilo de programação que aproveita certas estruturas "orientadas a objetos".

Os livros de algoritmo muitas vezes evitam a POO porque estão focados no algoritmo, não na estrutura. Fragmentos de código que dependem fortemente da estrutura tendem a ser exemplos ruins para colocar em um livro de algoritmos. Da mesma forma, os livros de POO muitas vezes evitam os algoritmos porque desordenam a história. O ponto de venda do OOP é sua fluidez, e vinculá-lo a um algoritmo faz com que pareça mais rígido. É mais sobre o foco do livro do que qualquer outra coisa.

No código da vida real, você usará os dois lado a lado. Você não pode resolver problemas do computador sem algoritmos, por definição, e é difícil escrever bons algoritmos sem estrutura (OOP ou não).

Como um exemplo de onde eles ficam borrados, use a Programação dinâmica. Em um livro de algoritmos, você descreveria como obter um conjunto de dados homogêneo em uma matriz e usar a Programação Dinâmica para chegar a uma solução. Em um livro OOP, você pode encontrar uma estrutura como Visitor, que é uma maneira de executar algoritmos arbitrários em um conjunto de objetos heterogêneos. O exemplo do livro do DP pode ser considerado um Visitante muito simples, operando em objetos em uma ordem geralmente ascendente. O padrão Visitor pode ser considerado o esqueleto de um problema de DP, mas falta a carne e as batatas. Na realidade, você encontrará muitas vezes as duas coisas juntas: você usa o padrão Visitor para lidar com a heterogeneidade em seu conjunto de dados (o DP é ruim nisso) e o DP na estrutura do Visitor para organizar seu algoritmo para minimizar o tempo de execução (Visitor não

Também vemos algoritmos operando sobre os padrões de design. É mais difícil expressar exemplos em um espaço pequeno, mas depois de ter estrutura, você começa a querer manipular essa estrutura e usa algoritmos para fazê-lo.

Existem alguns problemas que só podem ser apresentados e resolvidos pelo OOP?

Esta é uma pergunta mais difícil de responder do que você pensa. Na primeira ordem, não há razão computacional para você precisar de POO para resolver qualquer problema. A prova simples é que todo programa de POO é compilado no assembly, que é uma linguagem decididamente não-POO.

No entanto, no esquema maior das coisas, a resposta começa a se envergonhar para sim. Você raramente é limitado simplesmente por metodologias de computação. Na maioria das vezes, existem coisas como necessidades de negócios e habilidades de desenvolvedor que levam em consideração a equação. Atualmente, muitos aplicativos não poderiam ser escritos sem OOP, não porque o OOP é de alguma forma fundamental para a tarefa, mas porque a estrutura fornecida pelo OOP era essencial para manter o projeto no caminho e no orçamento.

Isso não diz que nunca abandonaremos a OOP no futuro por alguma nova estrutura engraçada. Apenas diz que é uma das ferramentas mais eficazes em nossa caixa de ferramentas para uma fração surpreendentemente grande de tarefas de programação disponíveis atualmente. Problemas futuros podem nos levar a abordar o desenvolvimento usando estruturas diferentes. Por um lado, espero que as redes neurais exijam uma abordagem de desenvolvimento muito diferente, que pode ou não ser "orientada a objetos".

Não vejo OOP desaparecendo em um futuro próximo devido à maneira como os designers de algoritmos pensam. Até o momento, o padrão usual é que alguém projete um algoritmo que não aproveite o OOP. A comunidade OOP percebe que o algoritmo não se encaixa realmente na estrutura OOP, e realmente não precisa, então eles envolvem todo o algoritmo em uma estrutura OOP e começam a usá-lo. Considere boost::shared_ptr. Os algoritmos de contagem de referência que ficam dentro shared_ptrnão são muito amigáveis ​​com OOP. No entanto, o padrão não ficou popular até a shared_ptrcriação de um wrapper OOP que expôs os recursos dos algoritmos em um formato estruturado OOP. Agora, é tão popular que chegou às especificações mais recentes para C ++, C ++ 11.

Por que isso é tão bem sucedido? Os algoritmos são ótimos na solução de problemas, mas geralmente requerem um investimento inicial substancial em pesquisa para entender como usá-los. O desenvolvimento orientado a objetos é muito eficaz para agrupar esses algoritmos e fornecer uma interface que requer menos investimento inicial para aprender.

Cort Ammon
fonte
1

Além das grandes respostas, mencionarei uma semelhança conceitual adicional entre OOP e algoritmos.

OOP e algoritmos enfatizam fortemente o uso de pré-condições e pós - condições para garantir a correção do código.

Em geral, essa é uma prática padrão em todas as áreas da ciência da computação; no entanto, esse princípio orientador resulta em um caminho evolutivo na OOP que torna mutuamente benéfico implementar algoritmos no ambiente da OOP.

No OOP, um grupo de objetos que podem satisfazer o mesmo contrato (pré-condições e pós-condições) pode ser criado para implementar uma interface. O usuário dessa interface não precisará saber qual implementação é usada no objeto subjacente, exceto em algumas situações raras (nas quais ocorre uma abstração com vazamento).

Um algoritmo é uma implementação de etapas usadas para executar um cálculo, que aceita a pré-condição e produz a pós-condição.

Portanto, pode-se emprestar a idéia de abstração na forma de pré-condições e pós-condições, e aplicá-la a algoritmos. Você descobrirá que, às vezes, algoritmos complicados podem ser decompostos em etapas menores, e essas etapas menores podem permitir diferentes estratégias de implementação, desde que sejam cumpridas as mesmas condições e pós-condições.

Ao implementar algoritmos no OOP, é possível tornar essas etapas menores intercambiáveis.

Por fim, lembre-se de que FP e OOP não são mutuamente exclusivos. Tudo o que foi descrito acima também pode ser aplicável ao FP.

rwong
fonte
Obrigado pelo ponto! Como você disse, se o algoritmo é apenas algumas etapas, o OOP pode nos ajudar a fornecer etapas mais abstratas. Você apontou sobre "implementar algoritmos no OOP", modifiquei minha pergunta para perguntar: é sempre benéfico?
Ahmad
11
você está confundindo POO com "Design por contrato". É muito bem útil, sem OOP, ea maioria das linguagens OOP (C #, Java) não fornecem suporte real para ele (eles suportam interfaces simples, não pré / pós-condições)
AK_
11
@AK_ Concordo que Design por Contrato é o nome correto para os pontos comuns descritos em minha resposta. O que estou afirmando é que OOP como paradigma de design abraça fortemente o Design by Contract - basta ler qualquer livro de OOP. Minha resposta original também menciona que essa semelhança não é exclusiva da OOP.
rwong 6/02
-1
What is the relation between algorithms and OOP? Are they two independent topics?

Os algoritmos são sobre como resolver um problema (como gerar saída a partir da entrada fornecida), OOP é sobre como formular ou expressar nossa solução (as etapas do algoritmo).

Um algoritmo pode ser descrito em linguagem natural ou em linguagem assembly, mas os conceitos que temos em uma linguagem natural nos ajudam a escrevê-lo e entendê-lo melhor. Por exemplo, o algoritmo para classificação de bolhas pode ser:

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

Para ocultar os detalhes swape relacioná-los com a Asintaxe e o recurso de OOP, o OO torna o algoritmo mais próximo da nossa linguagem e compreensão naturais.

Are there some problems which can only be presented and solved by OOP?

Não, se você considerar que qualquer programa (ou algoritmo) de um computador será traduzido para um conjunto de instruções executadas na CPU ( Turing Machine ) e se considerarmos essas instruções como o algoritmo final que resolve o problema em um computador , então OOP não pode fazer mais nada. Apenas o aproxima do entendimento e do raciocínio humano. É uma maneira de empacotar nossos procedimentos e estruturas de dados.

How OOP can help algorithms? Or in which direction it can affect it?

Pode ajudar a declarar ou formular um algoritmo mais fácil ou mais compreensível. Ele pode ocultar detalhes e fornecer uma imagem geral da solução.

Em teoria, o algoritmo é o primeiro e o implementa no segundo . Mas, na realidade, não podemos ter certeza de que nosso algoritmo funcione conforme o esperado até rastrear ou gerar a saída esperada. Os computadores nos ajudam a fazer isso, mas você não espera escrevê-lo em linguagem de máquina (assembly).

Nesse sentido, o POO facilita a implementação, teste e aprimoramento de nosso algoritmo em computadores e o escreve para um computador em um idioma próximo ao idioma natural.

Ahmad
fonte