Os campos públicos de Java são apenas uma falha trágica de design histórico neste momento? [fechadas]

17

Parece ser ortodoxia Java neste momento que basicamente nunca se deve usar campos públicos para o estado do objeto. (Não concordo necessariamente, mas isso não é relevante para a minha pergunta.) Dado isso, seria correto dizer que de onde estamos hoje, é claro que os campos públicos de Java foram um erro / falha do design da linguagem? Ou existe um argumento racional de que eles são uma parte útil e importante da linguagem, até hoje?

Obrigado!

Atualização: conheço as abordagens mais elegantes, como em C #, Python, Groovy etc. Não estou procurando diretamente esses exemplos. Estou realmente me perguntando se ainda há alguém no fundo de um bunker, murmurando sobre como os campos públicos são realmente maravilhosos e como as massas são todas apenas ovelhas, etc.

Atualização 2: Campos públicos finais claramente estáticos são a maneira padrão de criar constantes públicas. Eu estava me referindo mais ao uso de campos públicos para o estado do objeto (mesmo estado imutável). Estou pensando que parece uma falha de design que se deva usar campos públicos para constantes, mas não para o estado ... as regras de uma linguagem devem ser aplicadas naturalmente, pela sintaxe, não pelas diretrizes.

Avi Linho
fonte
2
Qual é a sua base para que eles sejam realmente uma falha?
Aaron McIver
1
Existe uma maneira diferente de criar expressões constantes simbólicas em Java agora?
Edward Strange
@ Aaron Eu não estava afirmando que eles são uma falha, eu estava afirmando que percebi que era ortodoxia neste momento que nunca se deve usar campos públicos. Essa percepção pode estar errada, mas é realmente o que eu percebi.
Avi Flax
@ Eddy Louco Esqueci esse uso, estava pensando mais no uso mais comum de campos, estado. Eu vou editar a pergunta.
Avi Flax

Respostas:

14

Gosto deles, desde que o campo seja final e seja usado apenas internamente no aplicativo, não exposto em uma API para outros aplicativos. Isso mantém seu código mais curto e mais legível.

Você não deve expor campos públicos em uma API porque, ao expor campos públicos, você também expõe a implementação. Se você o expuser como getXXX()método, poderá alterar a implementação sem alterar a interface da API. Por exemplo, você pode alterar e obter o valor de um serviço remoto, mas os aplicativos que usam a API não precisam saber disso.

Esse é um design viável para public finalcampos em classes imutáveis .

Do Java eficaz :

Item 14: Nas classes públicas, use métodos acessadores, não campos públicos

... se uma classe é privada de pacote ou é uma classe aninhada privada, não há nada inerentemente errado em expor seus campos de dados. Essa abordagem gera menos confusão do que a abordagem do método acessador.

Embora nunca seja uma boa ideia para uma classe pública expor campos diretamente, é menos prejudicial se os campos forem imutáveis.

Consulte também Por que não devo usar POJOs imutáveis ​​em vez de JavaBeans?

Jonas
fonte
Basta saber, quais são os seus motivos para não expô-lo em uma API?
Steven Jeuris
2
@ Steven: Porque, ao expor os campos públicos, você também expõe a implementação. Se você o expuser como getXXX()método, poderá alterar a implementação sem alterar a interface da API. Por exemplo, você pode alterar e obter o valor de um serviço remoto, mas os aplicativos que usam a API não precisam saber disso.
Jonas
@ Jonas: Esses geralmente não são candidatos a constantes em primeiro lugar.
Steven Jeuris
@ Steven: Não estou falando de constantes em primeiro lugar, mas de campos finais públicos em classes imutáveis . Por exemplo, consulte Por que não devo usar POJOs imutáveis ​​em vez de JavaBeans?
Jonas
@Jonas: Esse é um bom caso de uso também! Talvez seja útil atualizar um pouco sua resposta para esclarecer.
Steven Jeuris
9

O uso de pares de métodos get / set é a falha trágica do design histórico. Não consigo pensar em outra linguagem que implemente propriedades de maneira verbal e ineficiente.

Kevin Cline
fonte
1
Embora seja verdade, isso é algo tangencial ao ponto da pergunta, que é (essencialmente) que, dada a escolha entre métodos set / get e campos públicos, existem boas razões para preferir campos em alguma situação? Que outras línguas ofereçam melhores soluções para o problema me parece irrelevante.
Jules
5

Eu acho que os campos públicos são adequados para uma classe que é essencialmente um tipo de valor como um número complexo ou um ponto, onde a classe faz pouco mais do que agrupar tipos primitivos como uma estrutura no estilo C e talvez definir alguns operadores.

Karl Bielefeldt
fonte
2
java.awt.Pointe amigos são um pesadelo.
Tom Hawtin - tackline
@ TomHawtin-tackline: O problema Pointé que é ambíguo se uma variável do tipo Pointdeve encapsular um local ou se deve encapsular a identidade de uma entidade com um local que pode mudar. Conceitualmente, eu consideraria o código que passa por aí Pointcomo o código que passa por arrays.
Supercat 23/12
Portanto, se eu obtiver um Pointe modificá-lo, devo esperar que o objeto a que ele se refira seja atualizado corretamente na tela? Não, o problema Pointé que é mutável. Nós tínhamos String/ StringBuffermas a idéia não parecia ter sucesso. / Passar matrizes ao redor tem problemas semelhantes.
Tom Hawtin - tackline
5

Para definir constantes públicas, ainda é útil. Por exemplo

final estático público int DAYS_IN_WEEK = 7;

No entanto, ainda prefira enum sempre que possível. Por exemplo

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

Para simular classes simples de estrutura também é útil. Não há razão para criar um getter e setter para todos os campos, quando todos são públicos de qualquer maneira.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
Steven Jeuris
fonte
Mas, novamente, muitos argumentam estruturas não têm lugar em uma linguagem como Java ...
1
@ delnan: Eles são quase os mesmos do JavaBeans, mas o JavaBeans é muito mais detalhado e não é seguro para threads. Consulte Por que não devo usar POJOs imutáveis ​​em vez de JavaBeans?
Jonas
Algumas observações específicas do Android: Enums são mais lentas para avaliar do que ints e devem ser evitadas. Além disso, os campos freqüentemente acessados ​​por setters e getters em loops apertados também podem se beneficiar por serem públicos.
Nailer
2

Antes que os IDEs se generalizassem, tornar públicos todos os seus campos era uma ferramenta poderosa para criar protótipos / provas de conceitos rapidamente.

Atualmente, há muito pouca desculpa para usá-los, quando você pode gerar um par getter / setter com um clique do mouse.

Biziclop
fonte
4
Mas 10 public finalcampos são mais legíveis que 10 getXXX()métodos.
Jonas
1
@ Jonas Sim, mas não estamos falando de campos finais aqui. Se seus campos finais públicos também são estáticos, são constantes e uma constpalavra - chave seria suficiente; se não forem estáticos, eles são uma violação grave do encapsulamento.
biziclop
3
@biziclop de acordo com a Wikipedia : "apesar de reservada como uma palavra-chave em Java, const não é usada e não tem função"
Avi Flax
@Avi Flax Sim, mas poderia ter sido usado para marcar constantes, eliminando assim a necessidade de declarar constantes como campos públicos.
22411 biziclop
2
Supondo que um par getter / setter seja de todo apropriado, isso é. Muitas vezes não é.
David Thornley
2

Isso é subjetivo, mas minha opinião é que toda a noção pública / privada está desatualizada e atrasada.

Em python não há público / privado; tudo é público basicamente. Não causou muitos problemas.

Em Java, você tende a criar getters / setters inúteis para cada campo, para evitar o pecado de marcá-los como "públicos". (IMHO, se você estiver fazendo isso, basta marcá-los como públicos).

hasen
fonte
O Python permite que você marque as coisas como privadas, prefixando os nomes com __. Não é 100% privado, pois ainda existem maneiras de acessar essas variáveis ​​e métodos, mas, em C #, você pode fazer coisas semelhantes com reflexão.
Adam Lear