En este video de Rich Hickey , el creador de Clojure, aconseja utilizar el mapa para representar datos en lugar de usar una clase para representarlo, como se hace en Java. No entiendo cómo puede ser mejor, ya que cómo puede el usuario API saber cuáles son las claves de entrada si simplemente se representan como mapas.
Ejemplo :
PersonAPI {
Person addPerson(Person obj);
Map<String, Object> addPerson(Map<String, Object> personMap);
}
En la segunda función, ¿cómo puede el usuario API saber cuáles son las entradas para crear una persona?
Respuestas:
Resumen Exagg'itive (TM)
Tienes algunas cosas.
Hay un inconveniente fatal.
La cuestión es que puedes obtener introspección usando, um, introspección. Esto es lo que suele pasar:
En otras palabras, si nunca necesita interactuar con FP, no tiene que seguir el consejo de Rich Hickey.
Por último, pero no menos importante (ni el más bonito), aunque usar
String
como clave de propiedad tiene el sentido más directo, no tiene que usarString
s. Muchos sistemas heredados, incluido Android ™, utilizan ID de números enteros ampliamente en todo el marco para referirse a clases, propiedades, recursos, etc.Android es una marca registrada de Google Inc.
También puedes hacer felices a ambos mundos.
Para el mundo Java, implemente los captadores y establecedores como de costumbre.
Para el mundo FP, implemente el
Object getPropertyByName(String name)
void setPropertyByName(String name, Object value) throws IllegalPropertyChangeException
List<String> getPropertyNames()
Class<?> getPropertyValueClass(String name)
Dentro de estas funciones, sí, código feo, pero hay complementos IDE que lo llenarán por ti, usando ... uh, un complemento inteligente que lee tu código.
El lado de Java de las cosas será tan eficiente como de costumbre. Nunca usarán esa parte fea del código. Es posible que incluso desee ocultarlo de Javadoc.
El lado FP del mundo puede escribir el código "leet" que quieran, y generalmente no te gritan porque el código es lento.
En general, el uso de un mapa (bolsa de propiedades) en lugar del objeto es común en el desarrollo de software. No es exclusivo de la programación funcional ni de ningún tipo particular de lenguajes. Puede que no sea un enfoque idiomático para un idioma determinado, pero hay situaciones que lo requieren.
En particular, la serialización / deserialización a menudo requiere una técnica similar.
Solo algunas ideas generales sobre "mapa como objeto".
fuente
commonplace
me parece un poco fuerte Quiero decir, se usa como lo describe, pero también es una de esas cosas notoriamente frágiles / poco frágiles (como conjuntos de bytes o punteros vacíos) que las bibliotecas hacen todo lo posible por esconderse.Esa es una excelente charla de alguien que realmente sabe de lo que está hablando. Recomiendo a los lectores que lo vean todo. Solo dura 36 minutos.
Uno de sus puntos principales es que la simplicidad abre oportunidades para el cambio más adelante. La elección de una clase para representar a
Person
proporciona el beneficio inmediato de crear una API verificable estáticamente, como señaló, pero eso conlleva el costo de limitar las oportunidades o aumentar los costos de cambio y reutilización más adelante.Su punto es que usar la clase podría ser una opción razonable, pero debería ser una elección consciente que viene con plena conciencia de su costo, y los programadores tradicionalmente hacen un trabajo muy pobre al notar esos costos, y mucho menos tomarlos en consideración. Esa elección debe reevaluarse a medida que crecen sus requisitos.
Los siguientes son algunos cambios en el código (uno o dos de los cuales se mencionaron en la charla) que son potencialmente más simples usando una lista de mapas en comparación con el uso de una lista de
Person
objetos:Map
de las primitivas en un formato transmisible es altamente reutilizable e incluso puede proporcionarse en una biblioteca.Person
Es probable que un objeto necesite un código personalizado para realizar el mismo trabajo).Solucionamos este tipo de problemas todo el tiempo y tenemos patrones y herramientas para ellos, pero rara vez nos detenemos a pensar si elegir una representación de datos más simple y flexible al principio hubiera facilitado nuestro trabajo.
fuente
Choosing a class to represent a Person provides the immediate benefit of creating a statically-verifiable API... but that comes with the cost of limiting opportunities or increasing costs for change and reuse later on.
Incorrecto e increíblemente falso. Se mejora su oportunidad para cambiar más adelante, ya que cuando se realiza un cambio de última hora, el compilador encontrar y señalar que para cada lugar que necesita ser actualizado para llevar toda su código base a la velocidad de forma automática. ¡Es en código dinámico, donde no puedes hacer eso, que realmente te unes a las elecciones anteriores!Si los datos tienen poco o ningún comportamiento, con contenido flexible que puede cambiar, use un Mapa. OMI, un "javabean" u "objeto de datos" típico que consiste en un modelo de dominio anémico con N campos, N setters y N getters, es una pérdida de tiempo. No intentes impresionar a otros con tu estructura glorificada envolviéndola en una clase sofisticada y sofisticada. Sé honesto, deja en claro tus intenciones y usa un Mapa. (O, si tiene sentido para su dominio, un objeto JSON o XML)
Si los datos tienen un comportamiento real significativo, también conocido como métodos ( decir, no preguntar ), utilice una clase. Y date una palmada en la espalda por usar programación real orientada a objetos :-).
Si los datos tienen muchos comportamientos de validación esenciales y campos obligatorios, use una clase.
Si los datos tienen una cantidad moderada de comportamiento de validación, eso es límite.
Si los datos disparan eventos de cambio de propiedad, eso es realmente más fácil y mucho menos tedioso con un Mapa. Solo escribe una pequeña subclase.
Una desventaja principal del uso de un mapa es que el usuario tiene que convertir los valores en cadenas, ints, foos, etc. Si esto es muy molesto y propenso a errores, considere una clase. O considere una clase auxiliar que envuelva el Mapa con los captadores relevantes.
fuente
La API para a
map
tiene dos niveles.La API se puede describir en el mapa por convención. Por ejemplo, el par
:api api-validate
se puede colocar en el mapa o:api-foo validate-foo
podría ser la convención. El mapa incluso puede almacenarapi api-documentation-link
.El uso de convenciones permite al programador crear un lenguaje específico de dominio que estandariza el acceso a través de "tipos" implementados como mapas. El uso
(keys map)
permite determinar propiedades en tiempo de ejecución.Los mapas no tienen nada de mágico y los objetos no tienen nada de mágico. Todo es despacho.
fuente