In my application there are some actions that users can take, including redo
support.
Therefore, I felt the need to manage by objectizing Action
, and I implemented it as follows.
1. Implement RecoverableAction
abstract class RecoverableAction {
abstract fun getActionName(): String
abstract fun run()
abstract fun undoActionName(): String
enum class List(val action: RecoverableAction) {
CONTAINER_CREATE(ContainerActions.CREATE),
CONTAINER_COPY(ContainerActions.COPY),
CONTAINER_DELETE(ContainerActions.DELETE)
}
}
2. Implement Actions
for Redo
class ContainerActions private constructor() {
companion object {
val CREATE = object : RecoverableAction {
override fun run() {
//do create
}
override fun getActionName() = List.CONTAINER_CREATE.name
override fun undoActionName() = List.CONTAINER_DELETE.name
}
val DELETE = object : RecoverableAction {
override fun run() {
//do create
}
override fun getActionName() = List.CONTAINER_CREATE.name
override fun undoActionName() = List.CONTAINER_DELETE.name
}
val COPY = object : RecoverableAction {
override fun run() {
//do copy
}
override fun getActionName() = List.CONTAINER_CREATE.name
override fun undoActionName() = List.CONTAINER_DELETE.name
}
}
}
3. Do Action
anywhere 2 way
CotainerActions.CREATE.run()
RecoverableAction.List.CONTAINER_COPY.action.run()
I do not like using static
variables, but I do not want each Action
to be instantiated each time it is executed from the user. I also implemented it as a companion
so that I could run the corresponding Action
directly from several different classes.
In addition, I need to implement the redo
function by managing the actions executed by the user as a stack
. The reason I implemented the Action supported by RecoverableAction
as an enum
is because I want to manage it in the Action record stack
by name
rather than Action object
.
I have been thinking a lot about designing the structure to implement these requirements, but I think this can be a good structure. Could this be a "good way"?
To me,
RecoverableAction.List.CONTAINER_COPY.action.run()
Seems messy.
Why not:
sealed class RecoverableActions {
abstract val actionName: String
abstract val undoActionName: String
abstract fun run()
object CreateAction : RecoverableActions() {
override fun run() {
//do create
}
override val actionName = CreateAction::class.java.simpleName
override val undoActionName = DeleteAction::class.java.simpleName
}
object DeleteAction : RecoverableActions() {
override fun run() {
//do create
}
override val actionName = DeleteAction::class.java.simpleName
override val undoActionName = CreateAction::class.java.simpleName
}
object CopyAction : RecoverableActions() {
override fun run() {
//do create
}
override val actionName = CopyAction::class.java.simpleName
override val undoActionName = CopyAction::class.java.simpleName // ?
}
}
And
RecoverableActions.CreateAction.run()