O que se entende por "OOP esconde o estado"? [fechadas]

11

Em um dos muitos protestos anti-POO em cat-v.org , encontrei uma passagem de Joe Armstrong levantando várias objeções contra o modelo de POO, uma das quais era a seguinte:

Objeção 4 - Objetos possuem estado privado

O estado é a raiz de todo mal. Em particular, funções com efeitos colaterais devem ser evitadas.

Embora o estado nas linguagens de programação seja indesejável, no mundo real o estado é abundante. Estou muito interessado no estado da minha conta bancária e, quando deposito ou saio dinheiro do meu banco, espero que o estado da minha conta seja atualizado corretamente.

Dado que o estado existe no mundo real, que facilidades a linguagem de programação deve oferecer para lidar com o estado?

OOPLs dizem "ocultar o estado do programador". Os estados estão ocultos e visíveis apenas através das funções de acesso. As linguagens de programação convencionais (C, Pascal) dizem que a visibilidade das variáveis ​​de estado é controlada pelas regras de escopo da linguagem. Linguagens declarativas puras dizem que não há estado. O estado global do sistema é realizado em todas as funções e sai de todas as funções. Mecanismos como mônadas (para FPLs) e DCGs (linguagens lógicas) são usados ​​para ocultar o estado do programador, para que possam programar “como se o estado não importasse”, mas ter acesso total ao estado do sistema, caso isso seja necessário.

A opção "ocultar o estado do programador" escolhida pelos OOPLs é a pior opção possível. Em vez de revelar o estado e tentar encontrar maneiras de minimizar o incômodo do estado, eles o escondem.

O que exatamente se entende por isso? Tenho muito pouca experiência em procedimentos ou nível baixo, principalmente OOP, de modo que provavelmente explique o quanto eu não estou familiarizado com isso. E de um ponto de vista mais moderno, agora que a maioria da histeria orientada a objetos foi aprovada (pelo menos até onde eu sei), qual é a precisão / relevância que vocês acham que essa passagem é?

Obrigado pela ajuda.

Jake
fonte
3
leitura recomendada: discuta este $ {blog}
gnat
1
Se você me perguntar, o artigo ao qual você vinculou apresenta alguns argumentos bastante ruins (sem mencionar a qualidade da redação). Eu não colocaria muito estoque no que tem a dizer.
Benjamin Hodgson
1
Bah. Cada vez mais, acho que toda essa coisa "imutável" é uma boa ideia que está começando a cheirar mal de religião.
29414 Rob
3
Joe Armstrong reconheceu publicamente que suas objeções contra o OO se baseavam em graves mal-entendidos sobre o que exatamente é OO. Ele agora percebeu que Erlang é realmente uma linguagem profundamente orientada a objetos (na verdade, pode ser a linguagem mais orientada a objetos no uso convencional).
Jörg W Mittag
9
Para expandir: a primeira captura de archive.org do discurso de Joe Armstrong é de abril de 2001. Joe escreveu sua tese em 2003. Ao escrever sua tese, ele aprendeu muito sobre OO e percebeu que havia sido vítima do equívoco comum de que a OO estava de alguma forma relacionada ao estado mutável (não é, o estado mutável é completamente ortogonal). Desde então, ele reconheceu que suas críticas ao OO estavam erradas e que, ironicamente, Erlang é na verdade uma linguagem orientada a objetos (tem mensagens, tem objetos que chama de processos, tem encapsulamento).
Jörg W Mittag

Respostas:

32

O que exatamente se entende por isso?

Nesse contexto, significa que o OOP obscurece o estado de um programa, escondendo-o do programador, mas ainda o tornando visível através de métodos acessadores (com vazamento). O argumento é que, ao obscurecer o estado, torna mais difícil trabalhar e, por extensão, levar a mais erros.

quão preciso / relevante vocês acham que essa passagem é?

Eu sinto que é relevante, mas mal direcionado. Existe absolutamente um problema se sua classe vazar o conceito de seu estado para o mundo exterior. Existe absolutamente um problema se a sua turma tentar obscurecer o estado quando deve ser manipulado pelo mundo exterior. Isso, porém, não é uma falha do OOP como um todo, mas com o design individual da classe. Eu não diria que esconder o próprio estado é um problema - as mônadas fazem isso na programação funcional o tempo todo.

No melhor dos casos, o OOP funciona como a melhor combinação de programação funcional e processual - as pessoas podem usar a classe "como se o estado não importasse" porque o estado privado usado para proteger os invariantes da classe está oculto, mas tem liberdade usar um estado público bem definido da classe que abstraia os detalhes.

OOP torna mais difícil para as pessoas alcançarem esse melhor dos casos? Possivelmente. "Escolas Java" e toda a escola Forma / Círculo / Retângulo ou Carro têm o ensino de OO na Wheels, provavelmente têm mais culpa do que a própria abordagem. A OOP moderna se apóia bastante na programação funcional, incentivando objetos imutáveis ​​e funções puras, enquanto desencoraja a herança para ajudar a facilitar o design de classes que funcionam bem.

Telastyn
fonte
3
Concorde de todo o coração em toda a parte "escolas de java", não goste disso heh. Muito obrigado, eu votaria se pudesse.
Jake
2
Apenas para ser preciso: as mônadas em geral não escondem o estado, algumas mônadas (por exemplo, IO). Veja entre outros stackoverflow.com/questions/2488646/…
thSoft
2
+1. Esta é uma análise muito mais equilibrado e diversificado do que o artigo que o questioneer ligada
Benjamin Hodgson
2
Joe Armstrong reconheceu publicamente que suas objeções contra o OO se baseavam em graves mal-entendidos sobre o que exatamente é OO. Ele agora percebeu que Erlang é realmente uma linguagem profundamente orientada a objetos (na verdade, pode ser a linguagem mais orientada a objetos no uso convencional).
Jörg W Mittag
2
Jorg - você poderia postar um link para o acompanhamento de Joe? Eu estaria realmente interessado em lê-lo. E @radarbob, logo!
user949300
2

O raciocínio sobre um sistema será difícil se houver partes de estado mutável que não tenham um "proprietário" claro e único. Isso não significa que os objetos nunca devam ter um estado mutável, mas os objetos que têm um estado mutável não devem ser usados ​​de maneiras em que a propriedade não seja clara e, inversamente, que os objetos que precisarão ser passados ​​livremente sem rastrear a propriedade devem seja imutável.

Na prática, a programação eficiente freqüentemente requer que alguns objetos tenham um estado mutável; entretanto, esse estado deve ser confinado a objetos de trabalho não compartilhados . Considere as interfaces IEnumerable/ IEnumeratorno .NET: se uma coleção for implementada IEnumerable, ela permitirá que os itens sejam lidos um de cada vez. O processo real de leitura de uma coleção geralmente exige o controle de quais itens foram lidos (uma parte do estado mutável), mas esse estado não está contido na implementação de IEnumerable. Em vez disso, IEnumerablefornece um método chamado GetEnumeratorque retornará um objeto que implementa IEnumeratore contém estado suficiente para permitir a leitura de itens da coleção. O fato de o objeto conter esse estado não apresentará problemas, no entanto,se a implementação do objeto IEnumeratornão for compartilhada .

O melhor padrão na maioria dos casos é usar uma mistura de objetos que são compartilhados livremente, mas nunca serão modificados (pelo menos não depois de terem sido compartilhados) e objetos que tenham um proprietário claro e que possam ser modificados livremente por esse proprietário. , mas nunca são compartilhados com ninguém.

supercat
fonte
Excelente distinção entre o que deve ser imutável e o que pode ter um estado mutável. Ao ler isso, percebi que meus gráficos de objetos mais recentes (mais imutáveis ​​do que costumavam ser) seguem basicamente essa diretriz sem tê-la declarada tão claramente quanto você. Este é um bom antídoto moderado para o "estado mutável é sempre mau" que você ouve às vezes.
Mike suporta Monica
@ Mike: Eu acho que o verdadeiro problema é que todas as referências a objetos em Java e .NET são totalmente promíscuas; qualquer código que adquira ou receba uma referência a um objeto pode compartilhá-lo com qualquer outro código, sem restrição. Nenhuma estrutura possui qualquer conceito de um campo de referência não compartilhável; estruturas e referências no .NET se aproximam, mas são bastante limitadas em termos do que podem fazer ou do que podem impedir que código externo faça. Em qualquer caso, eu ofereceria um ditado fundamental em relação ao estado mutável: às 12:57 da manhã, um objeto pode representar simultaneamente ... #
24812
... o estado atual de um objeto do mundo real e o estado que o objeto tinha às 12h57. Se o estado real do objeto for alterado, não será mais possível que um objeto represente ambos. Às vezes, é necessário que o objeto continue representando o estado das 12:57 da manhã e, às vezes, o estado atual. A relação entre o estado 12:57 da manhã e o estado atual não pode permanecer, no entanto, se o estado atual for alterado.
precisa
0

Correndo o risco de ir além da resposta à pergunta, é fácil ver falhas na ideia de OOP, mas estou inclinado a pensar que o poder de uma idéia se reflete em sua capacidade de ser abusado.

Afinal, todo mundo tem seu idioma favorito, que eles descrevem em termos como "muito, muito poderoso", significando que realmente gostam dele . Mas a maravilha da universalidade computacional é que, por mais gloriosa que seja uma linguagem, se é verdadeiramente poderosa, ela pode simular a linguagem assembly. E se puder, alguém verá que sim. (Não que haja algo errado com a linguagem assembly.)

Meu sentimento pessoal sobre o movimento da OOP é que ele representa um atraso na educação das pessoas em engenharia de software / ciência da computação. Eles são atrofiados em um nível em que acham que é tudo sobre estrutura de dados. Classes, herança, contêineres, iteradores, mapas de hash, propriedades, ocultação de estado etc. - tudo sobre estrutura de dados - quanto mais, melhor.

Pessoalmente, eu gostaria de ver um próximo nível em que as pessoas aprendam a resolver problemas olhando-os linguisticamente. Onde eles entenderiam o conceito de linguagens específicas de domínio, como fazê-las facilmente e permitir que sua criação seja parte integrante da solução de problemas. Não é incorreto dizer que uma estrutura de dados é uma linguagem. As pessoas devem ter essa habilidade no design da linguagem, para que não estejam apenas atrapalhando.

Como próximo nível, eu gostaria de ver a inteligência artificial revigorada. Gostaria de ver os programadores irem além de bytes, threads e tabelas de funções virtuais e CUDAs, além de entender como fazer com que as máquinas raciocinem, aprendam e criem. Eu sei que isso avançou muito longe nos cantos do campo, mas nem de longe o suficiente.

Mike Dunlavey
fonte
1
"Se é realmente poderoso, pode simular a linguagem assembly" - você troca a definição de " powerfulali mesmo". Quando outros dizem powerful, eles falam sobre quão bem isso permite que os programadores abstraiam , o que é uma história diferente do poder computacional .
Phil
@Phil: abstrato é mais uma daquelas palavras :)
Mike Dunlavey
Nah. Você estava falando de palavras. Eu estava falando de idéias. Seu segundo e terceiro uso da palavra powersignificam coisas diferentes. Por favor, não confunda.
31414 Phil
Btw, se você estiver interessado, confira Racket , que é um pouco parecido com o que você está dizendo no seu quarto parágrafo (permitindo que os programadores levem a linguagem ao nível do problema em vez de fazê-los reduzir o problema para o conjunto fixo de construções da linguagem). Vai muito além do clássico Lisp / Scheme, para o caso de alguém ter essa impressão ao vê-lo pela primeira vez.
31414 Phil
0

A acessibilidade não é um recurso do OOP, é específica para implementações como Java e Microsoft dotNET. A principal característica que define a POO é o polimorfismo.

De qualquer forma, ocultando o estado do objeto, não há como criar uma API significativa. A apresentação é um componente vital da OOP do mundo real. Aqueles que discordam provavelmente têm uma hostilidade irracional em relação à indústria de software, o que torna sua opinião irrelevante do meu ponto de vista.

Sites como o que você vinculou são famosos por pensamentos extremamente rígidos e críticas a novas tecnologias. Algumas pessoas simplesmente não entendem.

Leopold Asperger
fonte
Um objeto deve existir para proteger os invariantes do conceito que modela. A apresentação é uma preocupação totalmente separada e não pode ser manipulada com eficiência e manutenção pelo mesmo objeto, porque um objeto não pode entender todas as várias maneiras pelas quais pode ser apresentado no tempo e no espaço. A apresentação deve ser tratada por meio de outro mecanismo, como streaming de eventos e visualizações materializadas, se o seu objetivo for objetos versáteis e de manutenção. A única vez que um objeto deve mudar é se seu conceito for revisado ou se seus invariantes mudam.
Andrew Larsson