java - interfaces - porque usar lambda aws
Pautas de uso de la interfaz de Java: ¿son malos y malos los setters en una interfaz? (11)
Escuché a la gente decir que, como regla general, una interfaz solo debe definir el comportamiento y no el estado. ¿Esto significa que una interfaz no debe contener getters y setters?
Para empezar, al menos con Java y sin incluir las declaraciones de excepción, no puede definir un comportamiento completo sin estado. En Java, las interfaces no definen el comportamiento. Ellos no pueden. Lo que ellos definen son tipos; promesas de implementar un conjunto de firmas de características posiblemente con algunas excepciones post-condiciones wrt. Pero eso es todo. El comportamiento y el estado se definen por las clases que implementan esas interfaces.
En segundo lugar, si los getters y los setters se definen en una interfaz, realmente no definen el comportamiento completo (otro que es para leer y otro para escribir una propiedad). Puede tener un comportamiento complejo detrás de los setters y getters, pero pueden solo se implementará en las clases reales. No hay nada en el lenguaje Java que nos permita definir libremente el comportamiento en las interfaces, excepto en los casos más restrictivos.
Teniendo eso en cuenta, no hay nada de malo, desde el punto de vista sintáctico y semántico, en tener setters y getters en las interfaces.
Si su aplicación está bien modelada y el problema requiere que tenga una interfaz que defina los adaptadores y los captadores, ¿por qué no? Por ejemplo, eche un vistazo a la interfaz ServletResponse.
Ahora, si observamos getters y setters desde el punto de vista de implementar clases que cumplan con las especificaciones de JavaBeans, entonces no necesita definir interfaces para ellas.
Pero si tiene cosas que requieren setters y getters, como podría ser un bean, y que también se debe conectar en compile-type (no en tiempo de ejecución como lo haría un bean), y para las que podrían existir múltiples implementaciones, entonces sí , esto requeriría una interfaz que defina getters y setters.
Espero eso ayude.
¿Qué piensa la gente sobre las mejores pautas para usar en una interfaz? ¿Qué debería y no debería entrar en una interfaz?
Escuché a la gente decir que, como regla general, una interfaz solo debe definir el comportamiento y no el estado. ¿Esto significa que una interfaz no debe contener getters y setters?
Mi opinión: Tal vez no sea así para los instaladores, pero a veces creo que los getters son válidos para colocarlos en una interfaz. Esto es simplemente para hacer cumplir las clases de implementación para implementar esos getters e indicar que los clientes pueden llamar a esos getters para verificar algo, por ejemplo.
Básicamente, si la respuesta a "¿Necesito saber el valor de [state, property, whatever-thhignAMaGit] para poder trabajar con una instancia de este?" entonces sí ... los accesores pertenecen a la interfaz.
List.size () de John arriba es un ejemplo perfecto de un getter que debe definirse en una interfaz
Creo que hay dos tipos de interfaces declaradas en general:
- una descripción del servicio . Esto podría ser algo así como
CalculationService
. No creo que los métodosgetX
deberían estar en este tipo de interfaz, y ciertamente nosetX
. Indican claramente los detalles de implementación, que no es el trabajo de este tipo de interfaz. - un modelo de datos : existe únicamente para abstraer la implementación de objetos de datos en el sistema. Pueden usarse para ayudar en las pruebas o simplemente porque algunas personas tan viejas como yo recuerdan los días en que (por ejemplo) usar un marco de persistencia te ligaba a tener una superclase particular (es decir, elegías implementar una interfaz en caso de que cambiases) tu capa de persistencia). Creo que tener métodos JavaBean en este tipo de interfaz es completamente razonable.
Nota: las clases de colecciones probablemente encajan en el tipo # 2
El hecho de que la implementación directa de algo sea como un getter no debería impedir que esté en una interfaz si es necesario.
Esto toca todo el tema de Getter / Setters malvado que se aborda varias veces en este sitio y en otros lugares.
Tiendo a preferir no tener accesores en la interfaz, sino agregar colaboradores usando argumentos de constructor para la implementación.
Los getters se utilizan para consultar el estado de un objeto, lo que realmente puede evitar al diseñar su interfaz. Lea http://www.pragprog.com/articles/tell-dont-ask
No creo que un bean tenga una interfaz encima, en general. Un javabean es una interfaz en el sentido más general. Una interfaz especifica el contrato externo de algo más complejo. El contrato externo de Java y su representación interna son idénticos.
Sin embargo, no diría que no deberías tener getters en una interfaz. Tiene mucho sentido tener una interfaz ReadableDataThingie implementada por DataThingieBean.
No hay nada intrínsecamente malo sobre los getters / setters. Sin embargo:
- Tiendo a hacer que mis objetos sean inmutables (en primera instancia) con respecto a los campos que contienen. Por qué ? Instalo la mayoría de las cosas durante la fase de construcción. Si quiero cambiar algo más tarde, relajo esas restricciones. Entonces mis interfaces tenderán a contener getters, pero no setters (hay otros beneficios, particularmente threading).
- Quiero que mis objetos hagan cosas por mí , no al revés. Entonces, cuando uno de mis objetos adquiere varios getters, empiezo a preguntar si ese objeto debería tener más funcionalidad, en lugar de exponer todos sus datos para que funcione algo más. Vea esta respuesta para más detalles.
Estas son todas las pautas, nota.
No veo por qué una interfaz no puede definir getters y setters. Por ejemplo, List.size()
es efectivamente un getter. Sin embargo, la interfaz debe definir el comportamiento en lugar de la implementación ; no puede decir cómo manejará el estado, pero puede insistir en que puede obtenerlo y configurarlo.
Las interfaces de recopilación son todas de estado, por ejemplo, pero diferentes colecciones pueden almacenar ese estado de maneras radicalmente diferentes.
EDIT: los comentarios sugieren que los getters y setters implican que se usa un campo simple para respaldar el almacenamiento. Estoy muy en desacuerdo con esta implicación. En mi opinión, hay una implicación de que es "razonablemente barato" obtener / establecer el valor, pero no que esté almacenado como un campo con una implementación trivial.
EDITAR: Como se señaló en los comentarios, esto se hace explícito en la sección de especificaciones JavaBeans 7.1:
Por lo tanto, incluso cuando un guionista escribe algo como
b.Label = foo
todavía hay una llamada de método al objeto de destino para establecer la propiedad, y el objeto de destino tiene control programático completo.Por lo tanto, las propiedades no solo tienen que ser campos de datos simples, sino que también se pueden calcular valores. Las actualizaciones pueden tener varios efectos secundarios programáticos. Por ejemplo, cambiar la propiedad de color de fondo de un frijol también podría hacer que el frijol se vuelva a pintar con el nuevo color ".
Si la supuesta implicación fuera cierta, también podríamos exponer las propiedades como campos directamente. Afortunadamente, esa implicación no se cumple : los captadores y establecedores están perfectamente dentro de sus derechos para computar las cosas.
Por ejemplo, considere un componente con
getWidth()
getHeight()
getSize()
¿Crees que hay una implicación de que hay tres variables allí? ¿No sería razonable tener:
private int width;
private int height;
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Size getSize() {
return new Size(width, height); // Assuming an immutable Size type
}
O (preferiblemente IMO):
private Size size;
public int getWidth() {
return size.getWidth();
}
public int getHeight() {
return size.getHeight();
}
public Size getSize() {
return size;
}
Aquí, la propiedad de tamaño o las propiedades de altura / ancho son solo para su comodidad, pero no veo que eso los invalide de ninguna manera.
Para lecturas adicionales: Confesiones de diseño de API práctica de un arquitecto de framework Java (Jaroslav Tulach, 2008, Apress).
Usé ese tipo de interfaces, por ejemplo, teníamos clases con los campos beginDate, endDate. Esos campos estaban en muchas clases y tenía un caso de uso que necesito para obtener esas fechas para diferentes objetos, así que extraje la interfaz y estaba muy feliz :)