Vantagens da programação orientada a objetos [fechada]

35

Nota : esta pergunta é um trecho editado de uma postagem de blog que escrevi há alguns meses atrás. Depois de colocar um link para o blog em um comentário no Programmers.SE alguém solicitou que eu publicasse uma pergunta aqui para que eles pudessem responder. Esta postagem é o meu mais popular, como as pessoas parecem tipo "Eu não entendo de programação orientada a objeto" no Google um monte . Sinta-se à vontade para responder aqui ou em um comentário no Wordpress.

O que é programação orientada a objetos? Ninguém me deu uma resposta satisfatória. Eu sinto que você não vai conseguir uma boa definição de alguém que sai por aí dizendo "objeto" e "orientado a objeto" com o nariz no ar. Você também não obterá uma boa definição de alguém que não fez nada além de programação orientada a objetos. Ninguém que entenda programação procedural e orientada a objetos jamais me deu uma idéia consistente do que realmente faz um programa orientado a objetos.

Alguém pode me dar suas idéias sobre as vantagens da programação orientada a objetos?

Joel J. Adamson
fonte
2
Ooh, legal - é difícil chegar a uma definição com a qual todos que dizem que fazem OOP concordam! (Mesmo negligenciando aqueles que realmente estão apenas fazendo, por exemplo, programação procedural em roupas OOP).
SamB
10
Realmente soa como "Eu não entendo programação C. Não podemos simplesmente usar a linguagem assembly?" para mim.
tia
2
@ Joel: Eu não conheço necessariamente os mesmos proponentes desinformados que você, mas acho que boa parte disso pode ser que eles foram introduzidos à programação por classes em linguagens OO. Se essa é sua linha de base, você não entende como isso é um avanço. Meu primeiro idioma era o Applesoft BASIC, e eu havia aprendido alguns dialetos do BASIC, além de C, Pascal e um pouco de assembly x86 antes de ser apresentado ao OOP pelo Delphi e C ++. Pessoas que experimentaram a diferença são mais capazes de explicá-la.
Mason Wheeler
3
Comentários mais negativos sobre OOP aqui: prejudicial.cat-v.org/software/OO_programming , incluindo citações de Dijkstra e Rob Pike.
Imgx64
3
@ Joel: Você acertou minha objeção à OOP na cabeça. As pessoas que são unânimes na OOP geralmente têm uma visão simplista da programação procedural e têm pouca ou nenhuma experiência em qualquer outro paradigma. A programação funcional pareceria totalmente estranha para eles (evidência: conte o número de pessoas recentemente perguntando como fazer classes e objetos em Erlang por algum motivo bizarro) e a programação lógica explodiria suas cabeças. Estou convencido. Eu só posso imaginar o que alguns dos paradigmas realmente estranhas faria para eles ....
apenas a minha opinião correta

Respostas:

7

Pense no software como uma máquina ou linha de montagem que existe dentro do computador. Algumas matérias-primas e componentes são alimentados na máquina e segue um conjunto de procedimentos para processá-los em algum produto final. Os procedimentos são configurados para executar uma operação específica em alguma matéria-prima ou componente de um conjunto específico de parâmetros (por exemplo, tempo, temperatura, distância etc.) em uma ordem específica. Se os detalhes da operação a ser executada estiverem incorretos, ou os sensores da máquina não estiverem calibrados corretamente, ou se alguma matéria-prima ou componente não estiver dentro dos padrões de qualidade esperados, isso poderá alterar o resultado da operação e o produto não sairá. como esperado.

Essa máquina é muito rígida em sua operação e entradas aceitáveis. Máquinas não questionam a inteligência dos projetistas nem seu ambiente operacional atual. Ele continuará a seguir os procedimentos, desde que direcionado. Mesmo que uma alteração nas matérias-primas ou nos componentes possa ter um efeito dramático no que aconteceu em operações posteriores, a máquina ainda executaria seus procedimentos. O processo precisaria ser revisto para ver quais alterações nos procedimentos eram necessárias para compensar e produzir o resultado desejado. Uma alteração no design ou na configuração do produto também pode exigir uma alteração significativa nas operações executadas ou em seu pedido. Embora os responsáveis ​​pela produção tenham aprendido rapidamente a importância de isolar as operações o máximo possível para reduzir os efeitos indesejáveis ​​entre eles, são feitas muitas suposições sobre a condição dos componentes quando eles são processados; suposições que podem não ser detectadas até que o produto final esteja nas mãos do usuário em algum ambiente operacional diferente.

É assim que é a programação procedural.

O que a orientação a objetos fornece é uma maneira de remover as suposições da condição dos componentes; portanto, as operações a serem executadas nesse componente e como integrá-lo ao produto final. Em outras palavras, OOP é como pegar os detalhes do processo para lidar com algum componente específico e entregá-lo a uma máquina menor. A máquina maior responsável pelo processo informa à máquina específica do componente qual operação ela espera que seja realizada, mas deixa os detalhes das etapas para a máquina específica do componente manipular.

Quanto às vantagens da orientação a objetos sobre o software não orientado a objetos:

  • comportamento específico do componente - tornando os detalhes de como lidar com um componente específico, a responsabilidade da máquina menor específica do componente garante que sempre que o componente for manuseado, sua máquina o fará adequadamente;
  • expressões polimórficas - como máquinas específicas de componentes executam operações personalizadas para seu componente específico, a mesma mensagem enviada para máquinas diferentes pode agir de maneira diferente;
  • abstração de tipo - geralmente faz sentido que vários tipos diferentes de componentes usem o mesmo vocabulário para as operações que suas máquinas fazem;
  • separação de preocupações - deixar detalhes específicos de componentes em suas máquinas significa que a máquina de processo precisa lidar apenas com as preocupações maiores e mais gerais de seu processo e com os dados necessários para gerenciá-la; além disso, é menos provável que seja afetado por alterações em outros componentes;
  • adaptabilidade - os componentes que se concentram em sua área de especialidade podem ser adaptados para uso imprevisto, simplesmente alterando os componentes que utiliza ou disponibilizando-o para outra máquina de processo;
  • reutilização de código - componentes com foco restrito e maior adaptabilidade podem alavancar seu custo de desenvolvimento ao serem usados ​​com mais frequência.
Huperniketes
fonte
3
Tudo o que você disse parece se aplicar igualmente à programação funcional, destacando o problema aqui.
Jesse Millikan
11
Exceto pelo fato de o OP não ter perguntado sobre programação funcional, seu comentário não tem mérito. Particularmente, já que minha resposta é a aceita.
Huperniketes
A programação funcional é naturalmente próxima a Orientada a Objetos, de fato, alguém poderia argumentar que a programação funcional é de fato uma forma mais "pura" de orientação a objetos, onde as próprias funções se tornam objetos de primeira classe. Ainda noob em toda essa coisa de programação funcional, ainda assim, é como me sinto no momento.
Newtopian
46

No seu blog, parece que você está familiarizado com a programação imperativa e funcional e com os conceitos básicos envolvidos na programação orientada a objetos, mas você nunca teve realmente um "clique" sobre o que torna útil. Vou tentar explicar em termos desse conhecimento e espero que seja útil para você.

Na sua essência, a OOP é uma maneira de usar o paradigma imperativo para gerenciar melhor os altos graus de complexidade, criando estruturas de dados "inteligentes" que modelam o domínio do problema. Em um programa (procedimento padrão não orientado a objetos), você tem duas coisas básicas: variáveis ​​e código que sabe o que fazer com elas. O código recebe a entrada do usuário e de várias outras fontes, armazena-a em variáveis, opera nele e produz dados de saída que vão para o usuário ou para vários outros locais.

A programação orientada a objetos é uma maneira de simplificar seu programa, pegando esse padrão básico e repetindo-o em uma escala menor. Assim como um programa é uma grande coleção de dados com código que sabe o que fazer com ele, cada objeto é um pequeno pedaço de dados vinculado ao código que sabe o que fazer com ele.

Ao dividir o domínio do problema em partes menores e garantir que o máximo de dados possível seja vinculado diretamente ao código que sabe o que fazer com ele, você facilita muito o raciocínio sobre o processo como um todo e também sobre os sub- questões que compõem o processo.

Ao agrupar dados em classes de objetos, você pode centralizar o código relacionado a esses dados, facilitando o código relevante para localizar e depurar. E, encapsulando os dados por trás dos especificadores de acesso e acessando-os apenas por métodos (ou propriedades, se o seu idioma os suportar), você reduz bastante o potencial de corrupção de dados ou violação de invariantes.

E usando herança e polimorfismo, você pode reutilizar classes preexistentes, personalizando-as para atender às suas necessidades específicas, sem ter que modificar os originais ou reescrever tudo desde o início. (O que é algo que você nunca deve fazer , se puder evitá-lo.) Apenas tome cuidado para entender seu objeto base ou poderá acabar com cangurus assassinos .

Para mim, esses são os princípios fundamentais da programação orientada a objetos: gerenciamento de complexidade, centralização de código e modelagem aprimorada de domínios de problemas através da criação de classes de objetos, herança e polimorfismo e segurança aumentada sem sacrificar o poder ou controle através do uso de encapsulamento e propriedades. Espero que isso ajude você a entender por que muitos programadores acham útil.

EDIT: Em resposta à pergunta de Joel nos comentários,

Você pode explicar o que um "programa orientado a objetos" contém (além dessas definições sofisticadas que você descreveu) que são fundamentalmente diferentes de um programa imperativo? Como você "faz a bola rolar?"

Um pequeno aviso aqui. Meu modelo de "um programa orientado a objetos" é basicamente o modelo Delphi, que é muito semelhante ao modelo C # /. NET desde que eles foram criados por ex-membros da equipe Delphi. O que estou dizendo aqui pode não se aplicar, ou não se aplica tanto, em outros idiomas OO.

Um programa orientado a objetos é aquele em que toda a lógica é estruturada em torno de objetos. Claro que isso precisa ser iniciado em algum lugar. Seu programa Delphi típico contém código de inicialização que cria um objeto singleton chamado Application. No início do programa, ele chama Application.Initialize, depois uma chamada Application.CreateFormpara todos os formulários que você deseja carregar na memória desde o início e, em seguida, Application.Run,exibe o formulário principal na tela e inicia o loop de entrada / evento que forma o núcleo de qualquer programas de computador interativos.

O aplicativo e seus formulários pesquisam os eventos recebidos do sistema operacional e os convertem em chamadas de método no seu objeto. Uma coisa que é muito comum é o uso de manipuladores de eventos, ou "delegados" no .NET-speak. Um objeto possui um método que diz "faça X e Y, mas também verifique se esse manipulador de eventos específico está atribuído e chame-o se for". Um manipulador de eventos é um ponteiro de método - um fechamento muito simples que contém uma referência ao método e uma referência à instância do objeto - usado para estender o comportamento dos objetos. Por exemplo, se eu tiver um objeto de botão no meu formulário, personalizo seu comportamento anexando um manipulador de eventos OnClick, que faz com que outro objeto execute um método quando o botão é clicado.

Portanto, em um programa orientado a objetos, a maior parte do trabalho é realizada definindo objetos com certas responsabilidades e vinculando-os, por meio de ponteiros de método ou por um objeto que chama diretamente um método definido na interface pública de outro objeto. (E agora estamos de volta ao encapsulamento.) Essa é uma ideia que eu não tinha noção de voltar antes de ter aulas de OOP na faculdade.

Mason Wheeler
fonte
4
Eu acho que você realmente acertou a cabeça com esta resposta. Quando você encapsula a manipulação de dados (OK, eles estão alocando um ponteiro aqui e depois deslocando alguns bits para lá ...) tudo o que resta é a lógica de alto nível do programa (Se feito corretamente, você pode escrever código horrível em qualquer paradigma .) .
ChaosPandion
2
Essa é uma ótima explicação, obrigado. Você pode explicar o que um "programa orientado a objetos" contém (além dessas definições sofisticadas que você descreveu) que são fundamentalmente diferentes de um programa imperativo? Como você "faz a bola rolar?"
Joel J. Adamson
11
+1: Eu acho que você realmente entendeu "está basicamente tentando repetir as mesmas coisas em uma escala menor", basicamente outro nível de abstração (ou melhor, mais como outro nível possível para criar abstração).
N1ckp 11/11/10
11
@ Karthik Um pouco atrasado para a festa, mas na verdade não, OOP não significa apenas reutilizar as aulas. Todo o conceito de um sistema de tipos é uma abstração para agrupar objetos em interfaces comuns. Mas você também pode usar um sistema baseado em protótipo (como Javascript) em que as chamadas de método no objeto resolvem a cadeia de protótipos em vez da cadeia de classes. Ele ainda possui todos os recursos do OOP, mas permite objetos e tipos ad-hoc simplesmente adicionando coisas novas a um objeto existente. Em seguida, você pode clonar esse objeto para obter mais desse novo tipo.
CodexArcanum
2
+1 por apontar exatamente a verdadeira vantagem do POO. "Na sua essência, OOP é uma maneira de usar o paradigma imperativo para melhor gerenciar um alto grau de complexidade através da criação de 'inteligentes' estruturas de dados que o modelo do domínio do problema."
Karthik Sreenivasan
6

Eu acho que OOP é basicamente apenas um nome dado a algo que você pode ter sido tentado a fazer ao longo do caminho, como eu era.

Quando eu era programador de bebês, mesmo em Fortran, havia um ponteiro para uma sub-rotina. É realmente útil poder passar um ponteiro para uma sub-rotina como argumento para outra sub-rotina.

A próxima coisa que seria realmente útil seria armazenar um ponteiro para uma sub-rotina dentro de um registro de uma estrutura de dados. Dessa forma, você pode dizer que o registro "sabe" como executar operações sozinho.

Não tenho certeza se eles construíram isso no Fortran, mas é fácil fazer isso em C e seus descendentes.

Então, por baixo, é uma idéia simples e útil que você pode ter tentado fazer sozinho, e é mais fácil de fazer em idiomas mais recentes, mesmo que algumas pessoas o transformem em um gigantesco movimento cheio de chavões assustadores.

Mike Dunlavey
fonte
5

Existem vários tipos de sistemas OO, e é difícil obter uma definição com a qual todos concordem. Em vez de tentar mostrar como o OO do Java é semelhante ao Common Lisp Object System, começarei com algo mais convencional, passo a passo.

Suponha que você tenha muitos objetos como dados dispersos. Os pontos, por exemplo, podem ser elementos em uma matriz X, Y e Z. Para considerar um ponto em si, faz sentido para puxar todos os dados juntos em algo como um C struct.

Agora, para qualquer objeto de dados, reunimos os dados. No entanto, em um programa processual, o código está disperso. Suponha que estamos lidando com formas geométricas. Há uma grande função para desenhar formas, e ela precisa conhecer todas as formas. Há uma grande função para encontrar a área e outra para o perímetro. O código para um círculo está espalhado por várias funções e, para adicionar outro tipo de forma, precisamos saber quais funções alterar. Em um sistema orientado a objetos, reunimos as funções no mesmo tipo de coisa ( class) que os dados. Portanto, se queremos olhar para todo o código do círculo, ele está na Circledefinição e, se queremos adicionar um Quartercircle, simplesmente escrevemos sua classe e obtemos o código.

Um lado beneficia disso é que podemos manter invariantes de classe, coisas verdadeiras sobre cada membro da classe. Ao restringir o código fora da classe de mexer diretamente com os membros dos dados da classe, temos todo o código que pode alterar os dados da classe em um só lugar e podemos confirmar que ele não faz nada de maluco (como ter um triângulo com uma perna mais do que os outros dois combinados). Isso significa que podemos contar com algumas propriedades de todos os membros da classe e não precisamos verificar se um objeto é sadio toda vez que o usamos.

O principal benefício vem com a herança e o polimorfismo. Ao definir todas essas formas como subclasses de uma classe chamada Shape, podemos fazer com que nosso código manipule Shapes, e é o trabalho dos subobjetos da forma fazer o que for exigido pelas manipulações. Isso significa que não precisamos tocar no código antigo testado quando adicionamos novas formas ou refinamos o comportamento das antigas. Temos automaticamente um código antigo que pode tirar vantagem diretamente do novo código. Em vez de tornar o código de controle ciente de todas as diferentes formas possíveis, e ter que manter funções cientes de todas as diferentes formas possíveis, apenas lidamos com as formas e suas propriedades, mantendo as Shapesubclasses. Isso simplifica o código de controle.

Temos várias vantagens aqui. Como temos invariantes de classe, podemos raciocinar sobre objetos de dados maiores da mesma maneira que raciocinar sobre tipos internos, o que significa que geralmente podemos dividir conceitos complexos em conceitos mais simples. Como o código do círculo está amplamente contido Circle, aumentamos a localidade. Como não há conceitos de círculo espalhados por várias funções diferentes em lugares diferentes, obtemos menos acoplamento entre as rotinas e não precisamos nos preocupar em mantê-las sincronizadas. Como as classes são, na verdade, tipos, podemos tirar proveito do sistema de tipos existente para capturar o uso incompatível de nossas classes.

David Thornley
fonte
3

OO tem muitas definições diferentes, sim. Tenho certeza que você pode encontrar muitos desses por conta própria. Eu, pessoalmente, gosto de Rees Re: OO como uma maneira de compreendê-los. Acho que você já leu isso desde que cita Paul Graham. (Eu recomendo a qualquer pessoa interessada em OO.) Vou adotar mais ou menos a definição de Java aqui {1,2,3,7,8,9}.

A questão da utilidade do OO, especialmente a maneira como a abordo, merece uma resposta muito maior com alguns milhares de linhas de código (em parte para não ser apenas um monte de afirmações). No entanto, aqui está um resumo desse documento hipotético.

Não acho que o OO seja muito útil em pequena escala, digamos, em algumas centenas de linhas. Em particular, linguagens OO sem boas influências funcionais tendem a tornar realmente doloroso realizar tarefas simples com qualquer tipo de coleção ou qualquer coisa que precise de muitos tipos de dados. É aqui que a maioria dos padrões de design entra em cena; eles são curativos na baixa potência do idioma subjacente .

Em cerca de mil linhas, torna-se mais difícil acompanhar todas as operações e estruturas de dados e como elas se relacionam. Neste ponto, ajuda a ter uma maneira de organizar explicitamente estruturas e operações de dados, definir limites de módulos e definir responsabilidades e ter uma maneira conveniente de entender essas definições enquanto você tenta programá-las.

O Java-ish OO é uma solução intermediária para esses problemas que venceram o concurso de popularidade. Como é o mesmo mecanismo que o pessoal de Java aplica aos problemas de pequena escala criados por uma linguagem pouco potente, ele tende a parecer mais uma solução mágica para tudo do que apenas uma maneira de se manter organizado. As pessoas familiarizadas com a programação funcional tendem a preferir outras soluções, como as classes de tipo CLOS ou Haskell, ou a metaprogramação de modelos quando presas em C ++, ou então (como eu, trabalhando diariamente em C #) usam OO, mas não ficam tão empolgadas com isso .

Jesse Millikan
fonte
+1 - Ótima resposta. "Não acho que o OO seja muito útil em pequena escala".
Karthik Sreenivasan
Até li um artigo ( dl.acm.org/citation.cfm?id=326103 ) afirmando que o OOP não mostra nenhuma vantagem real de produtividade em relação ao procedimento nas duas primeiras versões de um produto de software. Pelo que entendi, apenas a partir do terceiro lançamento você tem vantagens reais, porque é possível reutilizar / refatorar melhor o código escrito no estilo OO do que no estilo procedural.
Giorgio
1

OOP tenta modelar conceitos do mundo real em termos de objetos e interações entre eles. Como seres humanos, tendemos a processar o mundo em termos de objetos. O mundo está cheio de objetos que possuem certas propriedades e podem fazer coisas como interagir com outros objetos. OOP permite modelar o mundo em termos semelhantes. Por exemplo,

  • Pessoa é um objeto. Uma pessoa tem algumas propriedades, como idade e sexo. Uma pessoa pode fazer coisas: comer, dormir, dirigir um carro.
  • Carro também é um objeto (embora de tipo diferente). Também possui propriedades como marca, modelo e ano. Um carro pode fazer coisas: se mover.

Mas um carro não pode se mover sozinho, ele precisa de uma pessoa para dirigir - interação entre Objetos.

ysolik
fonte
Entendi: isso faz sentido. No entanto, acho que uma das coisas realmente legais sobre a programação de um computador é que não precisamos pensar em termos de como os objetos do "mundo real" fazem as coisas. Penso mais matematicamente (sou matemático fazendo pesquisas em biologia). Este foi um "a-ha" (uma visão meditativa), não uma atitude. No entanto, afetou muito a forma como faço meu trabalho.
Joel J. Adamson
1

OOP = estruturas de dados + passagem de mensagem + herança, todas evoluções lógicas nos modelos de programação.

OOP pode ser entendido (pelos programadores) em cerca de 90 segundos (veja meu perfil para obter um link). Os conceitos são muito simples.

Como aplicá-lo é outra questão. Só porque você sabe balançar um martelo não significa que você sabe como projetar e construir uma casa. ;-)

Steven A. Lowe
fonte
+1 - eu concordo. Como aplicar o POO silenciou muita prática e tempo, embora apenas saber o que são não demorou muito tempo, pois a implicação é a palavra-chave aqui.
Karthik Sreenivasan
0

Eu escrevi um post no blog há um tempo atrás que você pode achar útil: Procedural vs. OOP Explained .

VirtuosiMedia
fonte
Não sei por que as pessoas votaram contra! Este artigo é melhor do que todos os itens acima juntos! meu voto em +1
Haris
Seu voto foi negado porque é apenas um link-and-run, o que é altamente desencorajado. Veja a pergunta do meta stackoverflow: as respostas que contêm apenas links em outros lugares são realmente "boas respostas"?
Icc97
0

A maneira como eu entendi pela primeira vez é:

Antes da programação orientada a objetos, você tinha a programação estruturada . Tudo está centrado no processo. A primeira pergunta que você deve se fazer é " O que eu quero fazer com as informações? ".

Com a programação orientada a objetos, ela é centrada nos dados. A primeira pergunta que você deve se fazer é " Informações sobre as bruxas com as quais eu preciso lidar? ". Isso facilita a abstração.

DavRob60
fonte
0

Como você entende estruturas, e você entende ponteiros de função, e você entende estruturas com ponteiros de função, da sua perspectiva eu ​​definiria programação orientada a objetos como simplesmente "programação, com uso pesado de estruturas que possuem ponteiros de função". Ainda está programando no sentido tradicional - são todos os dados e códigos que atuam sobre os dados. A diferença é simplesmente como todas essas informações são definidas e como você as define.

Talvez uma simplificação exagerada seja que a programação tradicional é "código, com algumas estruturas de dados", e a programação orientada a objetos é "estruturas de dados, com algum código". Ambos ainda possuem estruturas de dados e ambos ainda possuem código. A programação orientada a objetos, portanto, nada mais é do que o ato de definir tipos de dados antecipadamente e impor contratos de como eles se comunicam por meio de conjuntos de funções.

Como você observou, há uma enorme classe de aplicativos para os quais essa não é uma ótima maneira de implementar uma solução. Você parece viver em um mundo predominantemente composto por esses aplicativos. No seu blog, você menciona as implementações do problema "99 garrafas de cerveja" (sua "vitrine de programação favorita"). 99 garrafas de cerveja certamente fazem parte dessa categoria. Tentar entender a programação orientada a objetos observando implementações de 99 garrafas de cerveja é como tentar entender a arquitetura de arranha-céus olhando uma casa na árvore. Mesmo uma casa na árvore muito bem construída só pode lhe ensinar muito.

A programação TL; DR: OO é como a programação tradicional, exceto que você concentra mais seu esforço em definir as estruturas de dados antecipadamente e essas estruturas de dados se comunicam entre si por meio de ponteiros de função.

Bryan Oakley
fonte
-1

Eu acho que a página da Wikipedia é um bom lugar para obter os fundamentos:
http://en.wikipedia.org/wiki/Object-oriented_programming

Basicamente, a idéia é que a programação procedural, que é o que a OOP estava tentando melhorar, focada nos processos que estão sendo modelados. OOP muda para um modelo em que o foco está nas "coisas" que você está modelando e os processos e dados dessas coisas estão contidos nessas coisas.

Então, como exemplo, digamos que você estava projetando um aplicativo para rastrear uma lista de tarefas. Na programação procedural, suas entidades de nível superior no modelo seriam os processos que ocorrem, como criar uma tarefa, remover uma tarefa, alterar as informações da tarefa etc. Em um modelo OOP, você focaria na criação de uma tarefa e pense sobre quais dados e processos pelos quais a Tarefa deve ser responsável. E, em seguida, concentre-se em com quais outros objetos a Tarefa deve interagir, como possivelmente uma Nota ou algo assim, se você deseja fazer anotações sobre Tarefas.

Espero que ajude. Continue lendo e olhando o código, e de repente ele "clicará". Essa foi a minha experiência.

RationalGeek
fonte
Downvoter cuidado para dar uma razão?
RationalGeek
Parece que você provavelmente nem leu toda a pergunta, muito menos cutucou a entrada do blog vinculado. O autor não tem um problema com os fundamentos, pelo que sei. Então, basicamente, -1 para responder a uma pergunta que você queria responder e não à pergunta que está sendo feita.
precisa