En la sugerente conferencia magistral de Rich Hickey " El valor de los valores ", a los 29 minutos, habla sobre la sobrecarga de un lenguaje como Java y hace una declaración como: "Todas esas interfaces matan su reutilización". ¿Qué quiere decir? ¿Es eso cierto?
En mi búsqueda de respuestas, me he encontrado con:
El Principio de Menos Conocimiento, también conocido como La Ley de Demeter, que fomenta las interfaces API herméticas. Wikipedia también enumera algunas desventajas.
La crisis de la ropa imperial de Kevlin Henney, que argumenta que el uso, no la reutilización, es el objetivo apropiado.
Charla de Jack Diederich " Stop Writing Classes " que argumenta en contra de la sobre ingeniería en general.
Claramente, cualquier cosa escrita lo suficientemente mal será inútil. Pero, ¿cómo impediría la interfaz de una API bien escrita que se use ese código? Hay ejemplos a lo largo de la historia de que algo hecho para un propósito se usa más para otra cosa . Pero en el mundo del software, si usa algo para un propósito para el que no fue diseñado, generalmente se rompe.
Estoy buscando un buen ejemplo de una buena interfaz que evite el uso legítimo pero no intencionado de algún código. ¿Existe eso? No puedo imaginarlo.
fuente
Respuestas:
No he visto la presentación completa de Rich Hickey, pero si lo entiendo correctamente, y a juzgar por lo que dice sobre la marca de 29 minutos, parece estar discutiendo sobre los tipos que matan la reutilización. Él está usando el término "interfaz" libremente como sinónimo de "tipo con nombre", lo cual tiene sentido.
Si tiene dos entidades
{ "name":"John" }
de tipoPerson
, y{ "name": "Rover" }
de tipoDog
, en Java-land, probablemente no puedan interactuar a menos que compartan una interfaz o ancestro común (comoMammal
, lo que significa escribir más código). Así las interfaces / tipos aquí son "matar a su reutilización": a pesar de quePerson
yDog
tienen el mismo aspecto, no se puede utilizar indistintamente con el otro, a menos que escribir código adicional para apoyar eso. Nota: Hickey también bromea sobre proyectos en Java que necesitan muchas clases ("¿Quién ha escrito una aplicación Java usando solo 20 clases?"), Lo que parece una consecuencia de lo anterior.Sin embargo, en los lenguajes "orientados al valor", no asignará tipos a esas estructuras; son solo valores que comparten la misma estructura (en mi ejemplo, ambos tienen un
name
campo con un valor de cadena) y, por lo tanto, pueden interoperar fácilmente, por ejemplo, se pueden agregar a la misma colección, pasar a los mismos métodos, etc.En resumen, todo esto parece ser algo sobre igualdad estructural versus igualdad explícita de tipo / interfaz . A menos que me haya perdido algo de las partes del video que aún no he visto :)
fuente
ERROR: Object doesn't have a property called "name"
a menudo es el resultado devalue-oriented
idiomas, y el otro problema es cuando ya no desea llamar a esa propiedadname
. Buena suerte refactorizando porque probablemente hay cientos de objetos con una propiedadname
pero no todos sonPerson
oDog
.interface
s, sino con el desorden que es el típico proyecto de Java.Es probable que se refiera al hecho básico de que una interfaz no puede ser instanciada. No se puede
reuse
una interfaz. Solo puede implementar código que lo admita, y cuando escribe código para una interfaz no hay reutilización.Java tiene un historial de proporcionar marcos de muchas API que toman una interfaz como argumentos, pero el equipo que desarrolló la API nunca implementa una amplia gama de clases para que pueda reutilizar con esas interfaces.
Es algo así como un marco GUI que tiene una
IWindow
interfaz para un cuadro de diálogo, y luego puede agregarIButton
interfaces para los controles. Excepto, nunca te dieron una buenaButton
clase que implementeIButton
. Entonces te quedas creando el tuyo.Los marcos abstraídos que tienen una amplia gama de clases base que proporcionan funcionalidades centrales son más reutilizables, y eso funciona mejor cuando esas clases abstractas son accesibles para aquellos que usan el marco.
Los desarrolladores de Java comenzaron a hacer esto donde sus capas API solo estaban expuestas
interfaces
. Podría implementar esas interfaces, pero nunca podría reutilizar las clases del desarrollador que implementó esas interfaces. Es como un estilo de capa y daga de desarrollo de API.fuente
Creo que la diapositiva 13 en su presentación ( El valor de los valores ) ayuda a comprender esto:
Según tengo entendido, Hickey sugiere que si necesito, por ejemplo, duplicar el valor que me enviaste, simplemente escribo un código como
Verá, el código anterior es el mismo, sin importar el tipo de valor que envió, una especie de reutilización perfecta .
Ahora, ¿cómo se vería esto en el lenguaje que tiene objetos e interfaces?
¡Oh espera! ¿Qué
YourValue
pasa si no se implementaDoublable
? no es que no se pueda duplicar, puede ser perfectamente, pero ... ¿y si simplemente no hay un métodoDouble
? (¿Qué pasa si hay un método llamado sayTwiceAsMuch
?)Uh, oh, tenemos un problema.
YourValue.Double
no funcionará, ya no se puede reutilizar . Según mi lectura de la diapositiva anterior, esto es sobre lo que Hickey quiso decir cuando dijo: "¡Todas esas interfaces matan su reutilización!"Verá, las interfaces suponen que los objetos se pasan "junto con sus métodos", junto con el código que opera en estos. Para usar objetos, uno necesita entender cómo invocar ese código, a qué método llamar.
Cuando falta el método esperado , hay un problema, aunque semánticamente , la operación deseada tiene mucho sentido para un objeto. Como se indicó en la presentación, los valores no necesitan métodos ("Puedo enviarte valores sin código y estás bien"), lo que permite escribir código que trata con ellos de manera genérica.
Nota al margen: la noción de pasar valores sin código de alguna manera me recuerda a un patrón Flyweight en OOP.
Los usos de peso mosca que he visto generalmente siguen el mismo enfoque de quitar el código (métodos, interfaces) de los objetos y pasar cosas como valores sin código , esperando que recibir código tenga los medios necesarios para operar en estos.
Esto se siente más o menos como en la diapositiva, "los valores no necesitan métodos. Puedo enviarle valores sin código y está bien".
fuente
MyValue = Double(YourValue)
no tiene sentido si YourValue es una cadena, una dirección, un usuario, una función o una base de datos. De lo contrario, su argumento de método perdido es fuerte. OTOH, los métodos de acceso le permiten imponer varias restricciones para que sus valores sean válidos y que solo se usen operaciones sensatas para producir nuevos valores. Si luego decide separar la Dirección de su Usuario y Empresa, los métodos de acceso significan que no romperá a todos los clientes de su código. Por lo tanto, pueden ayudar a reutilizar a largo plazo, incluso si a veces lo obstaculizan a corto plazo.En un (es decir, mi) clase mundial e interfaces ideales siempre describirían el comportamiento, pero el hecho es que con demasiada frecuencia realmente terminan describiendo datos. Ayer vi el video de alguien construyendo una supuesta
BankAccount
clase que no era más que una glorificadaint
(de hecho, era mucho menos útil que unaint
, por lo tanto, "matar" la reutilización que hubiera tenido si simplemente la hubiera dejado comoint
). todo en nombre del "buen" diseño. La cantidad de código, sudor y lágrimas desperdiciados en reinventar continuamente representaciones retorcidas de datos es asombrosa; Si no está utilizando los datos de manera significativa, simplemente déjelo.Ahora, esta es la etapa en la que Rich Hickey se contenta con tirar al bebé con el agua del baño y decir que todos deberíamos vivir en la tierra de los valores (un vecino del reino de los sustantivos). Creo, por otro lado, que la POO puede y promueve la reutilización (y lo que es más importante la capacidad de descubrimiento, que me parece que falta en la programación funcional) cuando se emplea con criterio. Si está buscando un principio OOP que mejor capture esta tensión, creo que podría ser http://c2.com/cgi/wiki?TellDontAsk (que por supuesto es un primo cercano de Demeter)
fuente