Me gustaría construir mi modelo de dominio utilizando solo objetos inmutables. Pero también quiero usar rasgos con campos val y mover algunas funcionalidades a rasgos. Por favor, mira el siguiente ejemplo:objetos inmutables Scala y rasgos con val campos
trait Versionable {
val version = 0
def incrementVersion = copy(version=version+1)
}
Desafortunadamente dicho código no funciona - método de copia es desconocida para el rasgo versionable.
Creo que sería bueno tener el método de copia generado para cada rasgo y clase. Tal método debe crear una copia superficial del objeto y devolverlo usando el mismo tipo que para el objeto original con el campo dado modificado de acuerdo con los argumentos pasados al método.
Así en el ejemplo siguiente:
class Customer(val name: String) extends Versionable {
def changeName(newName: String) = copy(name = newName)
}
val customer = new Customer("Scot")
customer.changeName("McDonnald")
debe devolver una instancia de objeto Customer(version = 0, name = "McDonnald")
y
customer.incrementVersion
debe también devolver una instancia de objeto Customer(version = 1, name = "Scot")
Por lo que yo sé la falta actual de tal funcionalidad en Scala no te permite Se inmutable clases y rasgos sin contaminante constructor de clase con campos de rasgo. En mi ejemplo, no deseo introducir el parámetro denominado versión en la clase Cliente porque la funcionalidad del manejo de la versión que quiero tener encapsulado en el rasgo de Versionable.
Conozco la funcionalidad del método de copia en las clases de casos y la capacidad de escribir el propio método de copia en clase usando parámetros predeterminados, pero creo que esta funcionalidad no resuelve mi problema porque no es posible usar dicho método rasgos. Otro inconveniente de la funcionalidad existente es que la clase primaria que utiliza el método de copia devuelve la clase principal y no la clase de objeto que realmente se copia.
Mis preguntas:
1) ¿Tiene usted idea de cómo manejar el ejemplo anterior en forma elegante. Soy bastante nuevo en Scala, así que quizás ya haya una buena solución. En mi opinión soluciones elegantes deben tener las características siguientes:
no debe utilizar la reflexión
no debe utilizar la serialización
debe ser rápido
debe ser verificable en tiempo de compilación
2) ¿Qué piensas acerca de escribir el complemento del compilador para generar código para el método de copia para el ejemplo anterior? ¿Es posible hacer eso usando el plugin de compilador? ¿Tienes algún ejemplo o consejos sobre cómo hacer eso?
¿Sabe usted que el caso cl Culos son dotados por el compilador con un método de 'copia' como usted describe? Las clases de casos no pueden (técnicamente, no deberían) derivar de otras clases de casos. En particular, la clase de caso derivada heredará el método 'copy' de la clase super (caso). –
Sí, lo sé y no voy a utilizar clases de casos para resolver el problema descrito. Estoy tratando de encontrar una solución para escribir clases inmutables con rasgos que no solo sean interfaces como en Java, sino que también agreguen implementación. Los métodos "Mutator" en tales rasgos deben devolver la copia del objeto con campos modificados "mutados" pero ¿cómo hacer esto de manera elegante? – Mariusz
Tal vez esta pregunta puede proporcionarle algunas formas útiles de lidiar con esto: http://stackoverflow.com/questions/3007464/minimal-framework-in-scala-for-collections-with-initing-return-type –