Cómo implementar Memento Pattern en Kotlin

Actualmente estoy tratando de implementar algunos patrones de layout en Kotlin como ejercicio y estoy un poco atrapado con el patrón 'Memento'. Mi recurso de reference es SourceMaking: Memento .

Quiero implementar esta estructura:

Diagrama de clase del patrón de diseño 'Memento'

Mientras siguen su "Lista de verificación"

  1. Identifica los roles de "cuidador" y "iniciador".
  2. Crea una class de Memento y declara al autor como un amigo.
  3. El cuidador sabe cuándo "controlar el punto" del originador.
  4. Originator crea un Memento y copy su estado a ese Memento.
  5. El cuidador se aferra (pero no puede asomarse) al recuerdo.
  6. El cuidador sabe cuándo "hacer retroceder" al originador.
  7. Originator se restablece utilizando el estado guardado en Memento.

No puedo hacer que el paso 5 funcione. ¿Cómo puedo hacer un object Memento cuyos campos se puedan leer desde dentro de la instancia de Originator pero que sea completamente opaco para el Caretaker ?

Lo he implementado con éxito en Java de la siguiente manera:

 public class Originator { private final int id; private String title; private String description; public Originator(int id) { this.id = id; } /* skipping title and description getter & setter */ public Memento saveState() { return new Memento(new State(id, title, description)); } public void restre(Memento memento) { id = memento.state.id; title = memento.state.title; description = memento.state.description; } private class State { private final int id; private final String title; private final String description; public State(int id, String title, String description) { this.id = id; this.title = title; this.description = description; } } public class Memento { private final State state; public Memento(State state) { this.state = state; } } } 

Y un cuidador

 public class Caretaker { public Originator originator; public Caretaker(@NotNull Originator originator) { this.originator = originator; } public Originator.Memento save() { return originator.saveState(); } public void restre(@NotNull Originator.Memento memento) { originator.restreFromState(memento); } } 

Debido a que son classs internas, puedo leer los campos privados de Memento y State desde mi instancia de Originator , pero para el Caretaker mi instancia de Memento es completamente opaca (solo muestra las funciones de miembro de Object ).

¿Ahora cómo implemento este comportamiento exacto en Kotlin? Básicamente me falta la funcionalidad de leer campos privados de classs internas.

Lo más cercano que pude pensar fue esto:

 class Originator(id: Long) { private var id: Long = id var description: String = "" var title: String = "" fun saveState() = Memento(State(id, title, description)) fun restreState(memento: Memento) { id = memento.state.id // <-- cannot access 'state': it is private in 'Memento' title = memento.state.title // <-- cannot access 'state': it is private in 'Memento' description = memento.state.description // <-- cannot access 'state': it is private in 'Memento' } inner class State(private val id: Long, private val title: String, private val description: String) inner class Memento(private val state: State) } 

Esto tiene el efecto deseado de que Memento sea ​​completamente opaco a mi instancia de Caretaker , pero tampoco puedo leer los campos desde Originator .
Este código por cierto es casi exactamente el mismo que el código generado producido por la function 'Convertir Java en Kotlin' de IntelliJ aplicado a mi código Java (y obviamente tampoco comstack).

Entonces, ¿hay algo obvio (o mágico) que me falta aquí? Tal vez algo más que la estructura que se muestra en el diagtwig de class? ¿O pueden estas especificaciones exactas simplemente no implementarse en Kotlin?

Y en otra nota: ¿el requisito de opacidad para el object Memento es en realidad una propiedad coloquialmente aceptada del Memento Pattern o hizo SourceMaking con este requisito?

Puede definir una class principal pública para Memento y una class henetworkingera privada para ella:

 class Originator { /* irrelevant declarations skipped */ abstract inner class Memento private inner class MementoImpl(val state: State) : Memento() fun saveState(): Memento { return MementoImpl(State(id, title, description)) } fun restre(memento: Memento) { memento as MementoImpl id = memento.state.id title = memento.state.title description = memento.state.description } } 

La class de implementación es private y, fuera de Originator , las instancias solo se verán como Memento (ver las firmas de function), de modo que no se podrá acceder al estado.

Debe definir sus properties de class Memento con acceso a nivel de package.