JavaRush /Blogue Java /Random-PT /Getters/Setters. Mal. E ponto final
angelina
Nível 5

Getters/Setters. Mal. E ponto final

Publicado no grupo Random-PT
Artigo de Egor Bugaenko 19 de setembro de 2014 | Postado em: Core Java Getters/Setters.  Mal.  E ponto - 1 Este antigo debate foi iniciado por Allen Holub em seu famoso artigo, em 2003, Por que os métodos getter e setter são maus - os getters/setters são um antipadrão e devemos evitá-los, ou é algo que devemos certamente será necessário na programação orientada a objetos. Acrescentarei meus dois centavos a esta discussão. A essência do texto abaixo é esta: getters e setters são más práticas; aqueles que os usam não têm desculpa. Mas, novamente, para evitar mal-entendidos, não estou sugerindo de forma alguma que o uso de get/set deva ser evitado sempre que possível. Não. Estou dizendo que você nem os deixou chegar perto do seu código . Getters/Setters.  Mal.  E ponto - 2O que você acha desta afirmação? Digno de sua atenção? Você usa o padrão get/set há 15 anos e é um arquiteto Java respeitado? E você nem quer ouvir essas bobagens de um estranho? Bem... eu entendo seus sentimentos. Eu me sentia da mesma maneira até encontrar o livro "Object Thinking" de David West - é o melhor livro sobre programação orientada a objetos que já li. Então por favor. Acalme-se e tente entender o que estou tentando explicar. Assunto de controvérsia Existem vários argumentos contra os "acessadores" (outro nome para getters e setters) no mundo orientado a objetos. E são todos argumentos muito corretos. Vamos dar uma olhada rápida neles. Pergunte, não conte : Allen Holub diz: "Não peça as informações de que você precisa para fazer um trabalho; 'peça' à entidade que possui essas informações para fazer o trabalho para você." Princípio de encapsulamento violado : um objeto pode ser desmontado por outros objetos porque eles são capazes de incorporar quaisquer dados no objeto, por meio de setters. Um objeto simplesmente não pode encapsular seu próprio estado com segurança suficiente porque qualquer um pode alterar esse estado. Detalhes de implementação revelados : se você pode obter um objeto de outro objeto, então estamos confiando demais nos detalhes de implementação do primeiro objeto. Se amanhã mudar (por exemplo, o tipo de resultado), teremos que alterar o código. Todas as justificações acima certamente fazem sentido, mas falta o ponto mais importante. Equívoco Básico A maioria dos programadores acredita que um objeto é uma estrutura de dados com métodos. Cito o artigo de Bozhidar Bozhanov: Getters e Setters não são maus. Mas a maioria dos objetos para os quais getters e setters são criados simplesmente contém dados. Este equívoco é o resultado de um enorme mal-entendido! Os objetos não “apenas armazenam dados”. Objetos não são estruturas de dados com métodos anexados. Este conceito de "armazenamento de dados" veio da programação orientada a objetos e das linguagens procedurais, especialmente C e COBOL. Repito novamente: um objeto não é apenas uma coleção de elementos de dados e funções que os manipulam. Um objeto não é um objeto de dados. E então? Bola e Cachorro Na verdadeira programação orientada a objetos, os objetos são seres vivos, assim como você e eu. São organismos vivos, com comportamento, propriedades e ciclo de vida próprios. Um organismo vivo pode ter um setter? Você pode prender (“fixar”) uma bola em um cachorro? Não pense. Mas é exatamente isso que o trecho de código abaixo faz:
Dog dog = new Dog();
dog.setBall(new Ball());
Então como você gosta? Você consegue (“tirar”) a bola do cachorro? Bem, vamos supor que você possa. Caso ela tenha comido e você tenha feito uma cirurgia nela. Nesse caso, sim, você conseguirá pegar (“pegar”) a bola do cachorro. É exatamente disso que estou falando:
Dog dog = new Dog();
Ball ball = dog.getBall();
Ou um exemplo ainda mais ridículo:
Dog dog = new Dog();
dog.setWeight("23kg");
Você pode imaginar isso na vida real? Parece que você escreve todos os dias? Se sim, então você é um programador processual. Apenas admita isso. Aqui está o que David West diz na página 30 de seu livro: O primeiro passo para transformar um desenvolvedor processual bem-sucedido em um desenvolvedor objetivo bem-sucedido é uma lobotomia. Você precisa de uma lobotomia? Eu definitivamente precisava disso, e consegui enquanto lia o livro "Object Thinking" de West. Pensamento objetivo Comece a pensar como um objeto e você imediatamente renomeará esses métodos. Aqui está o que você pode obter:
Dog dog = new Dog();
dog.take(new Ball());
Ball ball = dog.give();
Agora tratamos o cachorro como um animal de verdade que pode tirar a bola de nós e devolvê-la se pedirmos. Por precaução, observo que o cachorro não pode retornar NULL. Os cães simplesmente não sabem o que é NULL! O pensamento objetivo (pensamento) remove imediatamente as referências NULL do seu código. Getters/Setters.  Mal.  E ponto - 3
Um Peixe Chamado Wanda (1988) de Charles Crichton
Além disso, o pensamento objetivo resultará na imutabilidade de um objeto, como o “peso do cachorro” em nosso exemplo. Você reescreveria o código mais ou menos assim:
Dog dog = new Dog("23kg");
int weight = dog.weight();
Um cachorro é um organismo vivo imutável que não permite que ninguém de fora altere seu peso, tamanho, nome, etc. Ela pode “dizer”, mediante solicitação, seu peso ou nome. Não há nada de errado com métodos públicos que expõem consultas para determinadas propriedades “internas” de um objeto. Mas esses métodos não são “getters” e nunca deveriam receber o prefixo “get”. Nós não “saímos” do cachorro. Não sabemos o nome dela. Pedimos a ela que nos diga seu nome. Você vê a diferença? Não estamos nem falando de semântica aqui. Diferenciamos a abordagem processual da programação da abordagem orientada a objetos. Na programação processual, trabalhamos com dados, manipulamos, obtemos, configuramos e excluímos se necessário. Estamos no comando e os dados são apenas um componente passivo. Um cachorro não é nada para nós – ele simplesmente “contém dados”. Ela não tem vida própria. Podemos obter (obter) livremente tudo o que precisamos dele e colocar (definir) quaisquer dados nele. É assim que C, COBOL, Pascal e outras linguagens procedurais funcionam (funcionam). E a situação é completamente oposta no mundo orientado a objetos. Aqui tratamos os objetos como organismos vivos, com data de nascimento e momento de morte próprios, com personalidade e hábitos próprios, se preferir. Podemos pedir ao cão que nos forneça um dado (por exemplo, o seu peso) e ele pode devolver-nos a informação. Mas lembre-se sempre que o cão é o componente ativo. Ela decide o que acontece após o pedido. E é por isso que é absolutamente errado que os métodos de um objeto comecem com set ou get. E nem se trata de violar o encapsulamento, como muitos pensam. Trata-se do fato de você estar pensando como um objeto ou ainda estar escrevendo COBOL com sintaxe Java. PS . E sim, você pode perguntar: "E JavaBeans, JPA, JAXB e muitas outras APIs Java que dependem de get/set?" E quanto à função integrada em Ruby que facilita a criação de acessadores? Bem, o que posso dizer... você está sem sorte. É muito mais fácil permanecer no mundo primitivo do COBOL processual do que compreender e abraçar o maravilhoso mundo dos objetos reais. P.P.S._ _ Esqueci de dizer que sim, inserir dependências por meio de um setter também é um péssimo antipadrão. Mas mais sobre isso no próximo post! Artigo original
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION