Onde trabalho, vejo muitas classes que fazem coisas assim:
public class ClassThatCallsItsOwnGettersAndSetters {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public void methodWithLogic() {
setField("value");
//do stuff
String localField = getField();
//do stuff with "localField"
}
}
Se eu escrevesse isso do zero, teria escrito o methodWithLogic()
seguinte:
public class ClassThatUsesItsOwnFields {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public void methodWithLogic() {
field = "value";
//do stuff
//do stuff with "field"
}
}
Eu sinto que quando a classe chama seus próprios getters e setters, torna o código mais difícil de ler. Para mim, quase implica que uma lógica complexa está acontecendo nessa chamada de método, embora, no nosso caso, quase nunca ocorra. Quando estou depurando algum código desconhecido, quem pode dizer que o bug não é um efeito colateral nesse método? Em outras palavras, isso me faz fazer muitas viagens paralelas na jornada de compreensão do código.
Existem benefícios para o primeiro método? O primeiro método é realmente melhor?
java
object-oriented
programming-practices
Daniel Kaplan
fonte
fonte
Respostas:
Não vou dizer o que é melhor ou o pior, porque isso depende em parte da sua situação (na minha opinião). Mas considere que seus getters e setters podem alterar a implementação posteriormente, e ignorá-los ignoraria essa lógica.
Por exemplo, o que acontece se você adicionar um sinalizador "sujo" a alguns campos de incubação posteriormente? Ao chamar seus setters em seu código interno, você definirá o sinalizador sujo sem alterar nenhum outro código. Em muitas situações, isso seria uma coisa boa.
fonte
setField()
desde o início, acabou de introduzir um bug.Ligar para o setter diretamente não é, por si só, um problema. A pergunta realmente deveria ser: Por que nosso código tem setters em todos os lugares?
Classes mutáveis são um jogo perigoso, particularmente onde a própria classe gerencia seu próprio estado. Considere quantos desses levantadores realmente precisam existir. Quantos poderiam ser definidos no construtor e depois serem encapsulados inteiramente pela própria classe?
Se o campo deve ser configurável externamente, pergunte a si mesmo se o método com lógica deve estar lá. Sua própria classe é realmente apenas uma classe de dados / estado? Esta classe tem mais de uma responsabilidade?
Não me interpretem mal, haverá casos em que isso está bem. Não estou dizendo que você deva eliminar completamente os setters em classes com lógica. Mas estas devem ser a exceção, não a regra. E, nesses poucos casos, deve ser óbvio qual acessar diretamente.
fonte
Sim, os métodos da sua classe devem chamar os getters e setters. O ponto principal de escrever getters e setters é a prova do futuro. Você pode transformar todas as propriedades em um campo e expor diretamente os dados aos usuários da classe. A razão pela qual você cria os getters e setters não é necessariamente porque existe uma lógica complexa agora, mas para que a interface não seja quebrada no futuro, se você precisar adicioná-la.
fonte
someField=newValue; refresh();
Se o método permitir que vários campos sejam definidos, chamar setters para gravar esses campos causaria operações redundantes de "atualização". Escrever todos os campos e depois chamarrefresh()
uma vez pode render uma operação mais eficiente e de aparência mais suave.Para responder suas perguntas em uma palavra, sim.
Ter uma classe chamando seus próprios getters e setters adiciona extensibilidade e fornece uma base melhor para o código futuro.
Digamos que você tenha algo parecido com isto:
Chamar os setters por ano e make atualmente pode não adicionar nenhuma funcionalidade, mas e se você quiser adicionar algo como validação de entrada aos setters?
fonte
Uma coisa que não foi mencionada é que getter e setters (como todos os métodos) são virtuais em Java. Isso adiciona outro recurso para sempre usá-los em seu código. Outro usuário pode estender sua classe, substituindo seus getters e setters. Sua classe base usaria os dados da subclasse em vez de seus próprios. Em um idioma em que você marca explicitamente funções virtuais, isso é muito mais útil, pois você pode prever e declarar com quais funções isso pode ser feito. Em Java, isso é algo que você sempre deve estar ciente. Se o comportamento for desejado, usá-los em seu código é uma coisa boa, caso contrário, não muito.
fonte
Se você estiver tentando realizar algo que é fornecido pela interface pública, use os getters / setters.
No entanto, como proprietário / desenvolvedor da classe, você tem permissão para acessar as seções particulares do seu código (de dentro da classe, é claro), mas também é responsável por atenuar os perigos.
Portanto, talvez você tenha um getter que itera sobre alguma lista interna e deseja obter o valor atual sem incrementar o iterador. Nesse caso, use a variável privada.
fonte
Sim. Os getters e setters representam o estado, então vire essa questão - você deseja acompanhar várias maneiras de alterar o estado de um objeto da mesma maneira, a menos que precise?
Quanto menos coisas você precisar acompanhar melhor - é por isso que objetos imutáveis são mais fáceis de lidar.
Considere, não há nada que o impeça de ter um campo público e um getter / setter público - mas o que você ganha?
Por ocasião, pode ser desejável ou mesmo necessário acessar diretamente o campo por um ou mais motivos; você não deve se esquivar disso, se acontecer. Mas você realmente deve fazê-lo apenas se houver um benefício definido.
fonte
Ambos os métodos têm seus casos de uso. Como o setter público mantém o valor do campo (e / ou valores vinculados) consistente, você deve usar o setter quando a lógica do método não interferir nessa lógica de consistência. Se você acabou de definir sua "propriedade", use setter. Por outro lado, há situações em que você precisa de acesso direto a alguns campos, por exemplo, operações em massa com setter pesado ou operações em que o conceito do setter é muito simples.
É sua responsabilidade manter as coisas consistentes. O setter faz isso por definição, mas não pode cobrir casos complexos.
fonte
Eu diria que não ..
Se seus getters / setters apenas obtêm e configuram (sem inicialização lenta, sem verificações, etc), basta usar suas variáveis. Se, no futuro, você alterar seus getters / setters, poderá muito bem mudar seu
methodWithLogic()
(porque a classe está mudando) e poderá chamar um getter / setter em vez de uma atribuição direta. Você pode documentar esta chamada para o getter / setter (pois será estranho chamá-lo quando o restante do código da sua classe estiver usando diretamente a variável).A JVM incluirá chamadas frequentes para getters / setters. Portanto, nunca é um problema de desempenho. O ganho do uso de variáveis é legibilidade e IMHO, eu iria para ele.
Espero que isto ajude..
fonte