2010-02-08 11 views
6

Tengo una pregunta sobre el estilo de Java. He estado programando Java durante años, pero principalmente para mis propios fines, donde no tuve que preocuparme demasiado por el estilo, pero simplemente no tengo un trabajo en el que deba usarlo profesionalmente. Pregunto porque estoy a punto de hacer que la gente realmente revise mi código por primera vez y quiero que parezca que sé lo que estoy haciendo. Je.Pregunta de estilo getter/setter de Java

Estoy desarrollando una biblioteca que otras personas utilizarán en mi trabajo. La forma en que el otro código usará mi biblioteca es, básicamente, instanciar la clase principal y tal vez llamar a uno o dos métodos. No tendrán que hacer uso de ninguna de mis estructuras de datos, ni de ninguna de las clases que uso en segundo plano para hacer las cosas. Probablemente sea la persona principal que mantenga esta biblioteca, pero otras personas probablemente mirarán el código de vez en cuando.

Así que cuando escribí esta biblioteca, solo utilicé el nivel de acceso sin modificador predeterminado para la mayoría de mis campos, e incluso llegué a tener otras clases leídas ocasionalmente y posiblemente escribir desde/a esos campos directamente. Dado que esto está dentro de mi paquete, esta parecía una buena forma de hacer las cosas, dado que esos campos no van a ser visibles desde fuera del paquete, y parecía ser innecesario hacer las cosas privadas y proporcionar getters y setters. Nadie más que yo va a escribir código dentro de mi paquete, esto es de código cerrado, etc.

Mi pregunta es: ¿se verá esto como un mal estilo para otros programadores de Java? ¿Debería proporcionar getters y setters incluso cuando sé exactamente lo que obtendrá y establecer mis campos y no me preocupa que alguien más escriba algo que rompa mi código?

Respuesta

1

Sería muy reacio a entrar en una revisión de código con cualquier cosa que no sean campos privados, con la posible excepción de un campo protegido para el beneficio de una subclase. No te hará ver bien.

Claro, creo que desde la posición ventajosa de un experto en Java, puede justificar la desviación del estilo, pero como este es su primer trabajo profesional con Java, no está realmente en esa posición.

Así que para responder a su pregunta directamente: "¿Esto va a parecer un mal estilo?" Sí, lo hará.

¿Fue su decisión razonable? Solo si está realmente seguro de que este código no irá a ningún lado. En una tienda típica, puede haber posibilidades de volver a utilizar el código, factorizar las cosas en clases de utilidad, etc. Este código no será un candidato sin cambios significativos. Algunos de esos cambios se pueden automatizar con IDEs, y son básicamente de bajo riesgo, pero si su biblioteca está en un punto estable, probado y utilizado en producción, encapsularlo más tarde será considerado como un riesgo mayor de lo que era necesario.

+0

Gracias, la respuesta directa es lo que estaba buscando. Hay muchas buenas razones para usar getters y setters enumerados en otras respuestas. Tenía mis propios motivos para romper la encapsulación y quería saber si esto iba a ser algo que a otros programadores de Java realmente les interesaría. – jsn

1

Dado que usted es el único código de escritura en su paquete/biblioteca de código cerrado, no creo que deba preocuparse demasiado por el estilo, simplemente haga lo que funcione mejor para usted.

Sin embargo, para mí, trato de evitar el acceso directo a los campos porque puede hacer que el código sea más difícil de mantener y leer, incluso si soy el único responsable.

2

La mayoría de los desarrolladores de Java preferirán ver getters y setters.

Nadie puede ser desarrollo de código en el paquete, pero otros están consumiendo ella. Al exponer una interfaz explícitamente pública, puede garantizar que los consumidores externos utilicen su interfaz como espera.

Si expone una clase de implementación interna públicamente:

  • No es posible evitar que los consumidores utilizando la clase inapropiadamente
  • de control
  • Ha perdido más puntos de entrada/salida; cualquier campo público se puede mutar en cualquier momento
  • Aumentar el acoplamiento entre la aplicación interna y los consumidores externos

El mantenimiento de los captadores y definidores pueden tomar un poco más de tiempo, pero ofrece mucho más seguridad, más:

  • puede refactorizar su código en cualquier momento, de manera tan drástica como desee, siempre y cuando no se rompe la API pública (captadores, organismos, y los métodos públicos)
  • pruebas
  • Unidad de clases bien encapsulado es más fácil - se probar la interfaz pública y eso es todo (solo yo ur entradas/salidas a la "caja de negro")
  • herencia, composición y diseño de interfaces todos van a tener más sentido y sea más fácil de diseñar con las clases desconectados
  • decide que necesita añadir un poco de validación a un mutador antes ¿está puesto? Un buen lugar es dentro de un setter.

Depende de usted decidir si los beneficios valen la pena el tiempo adicional.

4

Me adheriría a un estilo común (y en este caso proporcionar setters/getters). Por qué ?

  1. es una buena práctica para cuando se trabaja con otras personas o proporciona bibliotecas de 3 partes
  2. una gran cantidad de marcos de Java asume convenciones captador/definidor y está labrado en busca de éstos/exponerlos/interrogarlos. Si no lo hace, sus objetos Java se cerrarán desde estos marcos y bibliotecas.
  3. si usa setters/getters, puede refactorizar fácilmente lo que hay detrás de ellos. Solo el uso de los campos limita directamente su capacidad para hacer esto.

Es realmente tentador adoptar un enfoque 'solo para mí', pero hay muchas convenciones, ya que las cosas se aprovechan de ellas, y/o son buenas prácticas por una razón. Trataría de seguir esto tanto como sea posible.

+0

En cuanto a 2, también es parte de la especificación JavaBean. – Powerlord

8

Incluso dentro de su paquete de fuente cerrada, la encapsulación es una buena idea.

Imagine que varias clases de su paquete acceden a una propiedad en particular y se da cuenta de que necesita, por ejemplo, almacenar en caché esa propiedad o registrar todo el acceso a ella, o cambiar de un valor almacenado real a un valor generas sobre la marcha. Tendría que cambiar muchas clases que realmente no deberían tener que cambiar. Estás exponiendo el funcionamiento interno de una clase a otras clases que no deberían necesitar saber acerca de esos funcionamientos internos.

+0

O bien, podría usar AOP para todos esos casos. –

+0

Además, en un frente mental, es más fácil captar una variable privada de un vistazo. Al instante sabe que hay limitaciones, no hay forma de que esto cambie a menos que algo en ESTE ARCHIVO lo modifique. Renunciar a la capacidad de guardar escribiendo algunos caracteres parece un delito. No me sentiría cómodo trabajando con alguien que lo hiciera a propósito. Tendría que suponer que no estaba pensando en el próximo programador en absoluto cuando estaba programando. . –

1

El estilo es una cuestión de convención. No hay una respuesta correcta, siempre y cuando sea consistente.

No soy fanático de camello, pero en el mundo Java, camelStyle gobierna supremo y todas las variables miembro deben ser privadas.

getData(); 
setData(int i); 

sigue el método del código Java de Sun Oficial (tos Oracle) y que debe estar bien.

http://java.sun.com/docs/codeconv/

+0

+1 para el enlace a la convención del código, he estado necesitando algo así – jsn

0

A pesar de que es doloroso, codificar hasta propiedades con captadores y definidores es una gran victoria si alguna vez va a utilizar sus objetos en un contexto como JSP (la lengua de expresión, en particular), OGNL, u otro lenguaje de plantilla. Si sus objetos siguen las buenas convenciones de Bean, entonces muchas cosas "simplemente funcionarán" más adelante.

0

Creo que los getters y setters son una mejor forma de programar y no se trata solo de una cuestión de convención de codificación. Nadie conoce el futuro, así que podemos escribir un número de serie simple hoy, pero mañana podríamos tener que poner "-" entre el código de área y el número, en ese caso, si tenemos un método getPhonenumber() definido, podemos hacer tales embellecimientos muy fácilmente. Así que me imagino, siempre debemos seguir este estilo de codificación para una mejor extensibilidad.

4

No creo que un buen idioma deba tener NINGÚN nivel de acceso, excepto privado - No estoy seguro de ver el beneficio.

Por otro lado, también tener cuidado con los captadores y definidores en absoluto - que tienen una gran cantidad de trampas:

  • Ellos tienden a fomentar el diseño OO malo (Por lo general, desea preguntar a su objeto de hacer algo para ti, no actúes sobre sus atributos)
  • Este mal diseño de OO hace que el código relacionado con tu objeto se disemine por diferentes objetos y, a menudo, conduce a la duplicación.
  • setters hacen su objeto mutable (algo que siempre es bueno para evitar, si puede)
  • setters y getters exponen sus estructuras internas (si tiene un getter para un int, es difícil cambiarlo a un doble -Tener que tocar cada lugar al que se accedió y asegurarse de que puede manejar un doble sin desbordamiento/causar un error, si en primer lugar le hubiera pedido a su objeto que manipule el valor, los únicos cambios serían internos a su objeto
+0

Por cierto, no estoy seguro de ver una gran diferencia entre una variable FINAL pública y una variable con un captador, excepto que a los programadores les gustan las "Reglas" y la "Regla" del colocador/captador es fácil de entender y atrás. Técnicamente, hay muy pocas razones para usar un getter en un campo final público, considerando las herramientas de refactorización en estos días, de hecho, diría que no hay absolutamente ninguna razón técnica, pero aún asustarás a muchos programadores que al igual que las reglas. –

1

Para ser breve, usted dijo "lo estoy preguntando porque estoy a punto de que la gente realmente revise mi código por primera vez y quiero que parezca que sé lo que estoy haciendo".Por lo tanto, cambie su código, ya que parece que no sabe lo que está haciendo.

El hecho de que lo haya levantado muestra que es consciente de que probablemente se verá mal (esto es algo bueno), y lo hace. Como se ha mencionado, está rompiendo los fundamentos del diseño de OO por conveniencia. Esto simplemente da como resultado un código frágil y, por lo general, inmanejable.

1

Romper la encapsulación es una mala idea. Todos los campos deben ser privados. De lo contrario, la clase no puede garantizar que se mantengan sus propias invariantes, porque alguna otra clase puede modificar accidentalmente los campos de forma incorrecta.

Tener getters y setters para todos los campos también es una mala idea. Un campo con getter y setter es casi lo mismo que un campo público: expone los detalles de implementación de la clase y aumenta el acoplamiento. El código que usa esos getters y setters viola fácilmente los principios de OO y el código se vuelve de procedimiento.

El código debe escribirse de modo que siga Tell Don't Ask. Puede practicarlo, por ejemplo, haciendo un ejercicio Object Calisthenics.

0

A veces uso public final propiedades sin/setter para objetos de vida corta que solo llevan algunos datos (y nunca harán nada más por diseño).

vez de eso, que realmente me gustaría si Java había dado a entender captadores y definidores creada usando una palabra clave property ...

2

No me importa mucho el estilo por sí mismo (o cualquier tipo de dogma de eso importa), sino más bien la conveniencia en facilidad de mantenimiento que viene con un conjunto de métodos getter/setter. Si usted (u otra persona) más tarde tuvo que cambiar el comportamiento asociado con un cambio de uno de esos atributos (registrar los cambios, hacerlo seguro para subprocesos, desinfectar los datos de entrada, etc.), pero ya los ha modificado directamente en muchos otros lugares en su código, habrá deseado utilizar los métodos getter y setter en su lugar.

+1

+1 para el aspecto de seguridad/concurrencia de hilo –

0

El uso de la encapsulación es una buena idea incluso para fuentes cerradas como ya se señaló en JacobM. Pero si su código actúa como biblioteca para otra aplicación, no puede evitar que la otra aplicación acceda a las clases que están definidas para uso interno. En otras palabras, no puede (?) Hacer cumplir la restricción de que una clase pública X solo puede ser utilizada por clases en mi aplicación.

Aquí es donde me gusta la arquitectura de plugins de Eclipse, donde puedes decir a qué paquetes de mi complemento pueden acceder los complementos durante el tiempo de ejecución. JSR 277 pretendía llevar este tipo de características modulares a JDK, pero ahora está muerto. Obtenga más información al respecto aquí, http://neilbartlett.name/blog/2008/12/08/hope-fear-and-project-jigsaw/

Ahora la única opción parece ser OSGi.