¿Son los campos públicos de Java solo una trágica falla de diseño histórico en este momento? [cerrado]

17

Parece ser la ortodoxia de Java en este punto que básicamente nunca se deben usar campos públicos para el estado del objeto. (No estoy necesariamente de acuerdo, pero eso no es relevante para mi pregunta). Dado eso, ¿sería correcto decir que desde donde estamos hoy, está claro que los campos públicos de Java fueron un error / falla del diseño del lenguaje? ¿O hay un argumento racional de que son una parte útil e importante del lenguaje, incluso hoy?

¡Gracias!

Actualización: conozco los enfoques más elegantes, como en C #, Python, Groovy, etc. No busco directamente esos ejemplos. Realmente me pregunto si todavía hay alguien en el fondo de un búnker, murmurando sobre lo maravillosos que son realmente los campos públicos, y cómo las masas son solo ovejas, etc.

Actualización 2: los campos públicos finales claramente estáticos son la forma estándar de crear constantes públicas. Me refería más al uso de campos públicos para el estado del objeto (incluso el estado inmutable). Estoy pensando que parece un defecto de diseño que uno debe usar campos públicos para constantes, pero no para el estado ... las reglas de un lenguaje deben aplicarse de manera natural, por sintaxis, no por pautas.

Avi Flax
fuente
2
¿Cuál es su base de que realmente son un defecto?
Aaron McIver
1
¿Hay alguna forma diferente de crear expresiones simbólicas constantes en Java ahora?
Edward Strange
@ Aaron No estaba afirmando que son un defecto, sino que he percibido que es una ortodoxia en este punto que uno nunca debe usar campos públicos. Esa percepción puede estar equivocada, pero de hecho es lo que he percibido.
Avi Flax
@Crazy Eddie Olvidé ese uso, estaba pensando más en el uso más común de los campos, estado. Editaré la pregunta.
Avi Flax

Respuestas:

14

Me gustan, siempre que el campo sea final y solo se use internamente en la aplicación, no expuesto en una API para otras aplicaciones. Esto mantiene su código más corto y más legible.

No debe exponer los campos públicos en una API porque al exponer los campos públicos, también expone la implementación. Si lo expones como un getXXX()método, puedes cambiar la implementación sin cambiar la interfaz API. Por ejemplo, podría cambiar y obtener el valor de un servicio remoto, pero las aplicaciones que usan la API no necesitan saberlo.

Este es un diseño viable para public finalcampos en clases inmutables .

De Java efectivo :

Elemento 14: en clases públicas, use métodos de acceso, no campos públicos

... si una clase es privada de paquete o es una clase privada anidada, no hay nada intrínsecamente incorrecto en exponer sus campos de datos. Este enfoque genera menos desorden que el enfoque del método de acceso.

Si bien nunca es una buena idea que una clase pública exponga los campos directamente, es menos dañino si los campos son inmutables.

Consulte también ¿Por qué no debería usar POJO inmutables en lugar de JavaBeans?

Jonas
fuente
Solo me pregunto, ¿cuáles son sus razones para no exponerlo en una API?
Steven Jeuris
2
@Steven: Porque al exponer los campos públicos, también expones la implementación. Si lo expones como un getXXX()método, puedes cambiar la implementación sin cambiar la interfaz API. Por ejemplo, podría cambiar y obtener el valor de un servicio remoto, pero las aplicaciones que usan la API no necesitan saberlo.
Jonas
@Jonas: En general, esos no son candidatos para constantes.
Steven Jeuris
@ Steven: No estoy hablando de constantes en primer lugar, sino de campos públicos finales en clases inmutables . Por ejemplo, vea ¿
Jonas
@Jonas: ¡Ese también es un buen caso de uso! Quizás sea útil actualizar un poco su respuesta para aclararla.
Steven Jeuris
9

El uso de pares de métodos get / set es la trágica falla de diseño histórico. No puedo pensar en otro lenguaje que implemente propiedades de forma vergonzosa e ineficiente.

Kevin Cline
fuente
1
Si bien es cierto, esto es algo tangencial al punto de la pregunta, que es (esencialmente) que dada la elección entre establecer / obtener métodos y campos públicos, ¿hay alguna buena razón para preferir campos en alguna situación? Me parece irrelevante que otros idiomas ofrezcan mejores soluciones al problema.
Jules
5

Creo que los campos públicos están bien para una clase que es esencialmente un tipo de valor como un número complejo o un punto, donde la clase hace poco más que agrupar tipos primitivos juntos como una estructura de estilo C y tal vez definir algunos operadores.

Karl Bielefeldt
fuente
2
java.awt.Pointy los amigos son una pesadilla.
Tom Hawtin - tackline
@ TomHawtin-tackline: El problema Pointes que es ambiguo si se supone que una variable de tipo Pointencapsula una ubicación, o se supone que encapsula la identidad de una entidad con una ubicación que puede cambiar. Conceptualmente, consideraría que el código que pasa Pointes muy similar al código que pasa alrededor de las matrices.
supercat
Entonces, si obtengo un Pointy lo modifico, ¿debo esperar que el objeto al que se refiere se actualice limpiamente en la pantalla? No, el problema Pointes que es mutable. Tuvimos String/ StringBufferpero la idea no pareció concretarse. / Pasar arreglos tiene problemas similares.
Tom Hawtin - tackline
5

Para definir constantes públicas todavía es útil. P.ej

public static final int DAYS_IN_WEEK = 7;

Sin embargo, todavía prefiero enum's donde sea posible. P.ej

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

Para simular clases simples de estructura también es útil. No hay razón para crear un getter y setter para cada campo, cuando todos son públicos de todos modos.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
Steven Jeuris
fuente
Pero, de nuevo, muchos dirían que las estructuras no tienen lugar en un lenguaje como Java ...
1
@delnan: Son casi lo mismo que JavaBeans, pero JavaBeans es mucho más detallado y no es seguro para subprocesos. Consulte ¿Por qué no debería usar POJO inmutables en lugar de JavaBeans?
Jonas
Algunas observaciones específicas de Android: las enumeraciones son más lentas para evaluar que las entradas y deben evitarse. Además, los campos a los que acceden frecuentemente los colocadores y captadores en bucles estrechos también pueden beneficiarse de ser públicos.
Clavador
2

Antes de que los IDE se generalizaran, hacer públicos todos sus campos era una herramienta poderosa para crear prototipos / pruebas de conceptos rápidamente.

Hoy en día hay muy pocas excusas para usarlos, cuando puedes generar un par getter / setter con un clic del mouse.

biziclop
fuente
44
Pero 10 public finalcampos es más legible que 10 getXXX()métodos.
Jonas
1
@ Jonás Sí, pero no estamos hablando de campos finales aquí. Si sus campos finales públicos también son estáticos, son constantes, y una constpalabra clave sería suficiente, si no son estáticos, son una violación grave de la encapsulación.
biziclop
3
@biziclop según Wikipedia : "aunque reservado como una palabra clave en Java, const no se usa y no tiene ninguna función"
Avi Flax
@Avi Flax Sí, pero podría haberse usado para marcar constantes, eliminando así la necesidad de declarar constantes como campos públicos.
biziclop
2
Asumiendo que un par getter / setter es apropiado, es decir. A menudo no lo es.
David Thornley
2

Esto es subjetivo, pero mi opinión es que toda la noción pública / privada está desactualizada y al revés.

En python no hay público / privado; todo es público básicamente. No ha causado muchos problemas.

En Java, tiende a crear captadores / establecedores sin sentido para cada campo para evitar el pecado de marcarlos como "públicos". (En mi humilde opinión, si te encuentras haciendo eso, solo debes marcarlos como públicos).

Hasen
fuente
Python le permite marcar cosas como privadas con el prefijo de los nombres con __. No es 100% privado, ya que todavía hay formas de acceder a esas variables y métodos, pero luego en C # puede hacer cosas similares con la reflexión.
Adam Lear