** Table of Contents ** The purpose of this pattern is to realize that the request can be edited dynamically by making the request into an object, and that maintenance management is simplified by combining a series of processes into one object and preparing a common interface. Is not it.
I often see this method.
Receiver.kt
fun run(mode: ModeType) {
when(mode) {
ModeType.Begin -> {
//Preparation process
loadProperty()
startDriver()
}
ModeType.Running -> {
//Main processing
running()
}
ModeType.After -> {
//End processing
saveState()
stopDriver()
}
}
}
private fun loadProperty(){}
private fun startDriver(){}
private fun running(){}
private fun saveState(){}
private fun stopDriver(){}
Since we needed to suspend, we wanted a mode that only called `saveState ()`
, so we'll add a mode and implementation.
Receiver.kt
ModeType.Interruption -> {
//Suspension processing
saveState()
}
In yet another mode ..., the `Receiver``` class has to be modified endlessly, and
Mode``` will increase steadily. By applying this pattern to this, it becomes possible to make it behave flexibly without modifying the ``
Receiver``` class.
By encapsulating the request as an object, the client is parameterized with different requests and queues and logs of requests. It also supports undoable operations.
An abstract class that defines the methods executed by the Command Receiver class -ConcreteCommand Command Class concrete class ・ Client users ・ Invoker -A class that knows how to issue a Receiver instruction
With interface
Receiver.kt
package command
interface Receiver {
fun getName(): String
}
Concrete class
Car.kt
package command
class Car(private val name: String): Receiver {
override fun getName(): String {
return "The receiver is${name}Is an object"
}
fun openDoor() {
println("open the door")
}
fun engineStart() {
println("Engine start")
}
fun engineStop() {
println("Engine stop")
}
fun lock() {
println("Lock")
}
fun unlock() {
println("unlock")
}
fun pushAxelPedal() {
println("Step on the accelerator")
}
fun pushBreakePedal() {
println("Step on the brake pedal")
}
}
Command.kt
package command
interface Command {
fun execute()
}
SimpleCommand.kt
package command
class SimpleCommand(private val receiver: Receiver, private val method: String): Command {
override fun execute() {
receiver.javaClass.getDeclaredMethod(method).invoke(receiver)
}
}
MacroCommand.kt
package command
import kotlin.collections.ArrayList
class MacroCommand: Command {
private val commandList = ArrayList<Command>()
override fun execute() {
commandList.forEach {
it.execute()
}
}
fun addCommand(command: Command) {
commandList.add(command)
}
fun removeCommand(command: Command) {
commandList.remove(command)
}
}
Client People who use Create a command to start the car engine.
Client.kt
package command
class Client {
init {
val receiver = Car("Prius")
createStartCarCommand(receiver).execute()
}
private fun createStartCarCommand(receiver: Car): Command {
val startCarCommand = MacroCommand()
startCarCommand.addCommand(SimpleCommand(receiver, "unlock"))
startCarCommand.addCommand(SimpleCommand(receiver, "openDoor"))
startCarCommand.addCommand(SimpleCommand(receiver, "engineStart"))
return startCarCommand
}
}
Execution result
[out-put]
unlock
open the door
Engine start
I wanted a command to stop the car engine.
Client.kt
package command
class Client {
init {
val receiver = Car("Prius")
createStopCarCommand(receiver).execute()
}
private fun createStopCarCommand(receiver: Car): Command {
val stopCarCommand = MacroCommand()
stopCarCommand.addCommand(SimpleCommand(receiver, "engineStop"))
stopCarCommand.addCommand(SimpleCommand(receiver, "openDoor"))
stopCarCommand.addCommand(SimpleCommand(receiver, "lock"))
return stopCarCommand
}
}
Execution result
[out-put]
Engine stop
open the door
Lock
I wanted to create a command to drive a car.
Client.kt
package command
class Client {
init {
val receiver = Car("Prius")
createCarRunCommand(receiver).execute()
}
private fun createCarRunCommand(receiver: Car): Command {
return SimpleCommand(receiver, "pushAxelPedal")
}
}
Execution result
[out-put]
Step on the accelerator
I needed a command to start the car engine, run for a while and then stop the engine.
Client.kt
package command
class Client {
init {
val receiver = Car("Prius")
createStartAndRunAndStopCarCommand(receiver).execute()
}
private fun createStartAndRunAndStopCarCommand(receiver: Car): Command {
val startAndRunAndStopCarCommand = MacroCommand()
startAndRunAndStopCarCommand.addCommand(createStartCarCommand(receiver))
val runCommand = createCarRunCommand(receiver)
startAndRunAndStopCarCommand.addCommand(runCommand)
startAndRunAndStopCarCommand.addCommand(runCommand)
startAndRunAndStopCarCommand.addCommand(runCommand)
startAndRunAndStopCarCommand.addCommand(runCommand)
startAndRunAndStopCarCommand.addCommand(createStopCarCommand(receiver))
return startAndRunAndStopCarCommand
}
private fun createStartCarCommand(receiver: Car): Command {
val startCarCommand = MacroCommand()
startCarCommand.addCommand(SimpleCommand(receiver, "unlock"))
startCarCommand.addCommand(SimpleCommand(receiver, "openDoor"))
startCarCommand.addCommand(SimpleCommand(receiver, "engineStart"))
return startCarCommand
}
private fun createCarRunCommand(receiver: Car): Command {
return SimpleCommand(receiver, "pushAxelPedal")
}
private fun createStopCarCommand(receiver: Car): Command {
val stopCarCommand = MacroCommand()
stopCarCommand.addCommand(SimpleCommand(receiver, "engineStop"))
stopCarCommand.addCommand(SimpleCommand(receiver, "openDoor"))
stopCarCommand.addCommand(SimpleCommand(receiver, "lock"))
return stopCarCommand
}
}
[out-put]
unlock
open the door
Engine start
Step on the accelerator
Step on the accelerator
Step on the accelerator
Step on the accelerator
Engine stop
open the door
Lock
Reading the applicability of the GoF book, the heart of this pattern is that you can ** cancel any request by objectifying the request **, the so-called `MacroCommand``` class
`removeCommand``` It seems to call a method, but I can't think of a situation that I need.
Recommended Posts