[GO] [Gang of Four] Design pattern learning --Command

Command --command

** 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.

Purpose

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.

Component

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

Implementation

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")
    }
}

An abstract class that defines the methods executed by the Command Receiver class

Command.kt


package command

interface Command {
    fun execute()
}

Concrete Command Command Class concrete class

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
    }
}

Output result

[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

[Gang of Four] Design pattern learning --Command
[Gang of Four] Design pattern learning
[Gang of Four] Design pattern learning --Singleton
[Gang of Four] Design Pattern Learning --Decorator
[Gang of Four] Design pattern learning --Visitor
[Gang of Four] Design pattern learning --Mediator
[Gang of Four] Design pattern learning --Iterator
[Gang of Four] Design pattern learning --Facade
[Gang of Four] Design pattern learning --Composite
[Gang of Four] Design pattern learning --Prototype
[Gang of Four] Design pattern learning --Memento
[Gang of Four] Design pattern learning --State
[Gang of Four] Design pattern learning --Interpreter
[Gang of Four] Design pattern learning --Builder
[Gang of Four] Design pattern learning --Bridge
[Gang of Four] Design pattern learning --Proxy
[Gang of Four] Design pattern learning --Adapter
[Gang of Four] Design pattern learning --Observer
[Gang of Four] Design pattern learning --Fly Weight
[Gang of Four] Design pattern learning --Abstract Factory
[Gang of Four] Design pattern learning --Factory Method
[Gang of Four] Design pattern learning --Chain of Responsibility
[Gang of Four] Design pattern learning --Template Method
Learn the design pattern "Command" in Python
Gang of Four (GoF) Patterns in Python
Design Pattern #Adapter
Design Pattern #Decorator
Pattern recognition learning in video Part 1 Field of Pattern Recognition
Design Pattern #Template Method
Template Method pattern in Java
Python Design Pattern --Template method
Design Pattern #Factory Method
Learn the design pattern "Template Method" in Python
[Gang of Four] Design pattern learning --Template Method
template
Design Pattern #Observer
Design Pattern #Facade
Design Pattern #Strategy
Design Pattern #Singleton
Learn the design pattern "Chain of Responsibility" in Python
memorandum of vi command
Design Pattern #Factory Method
Deep learning 1 Practice of deep learning
Design Pattern #Template Method
GoF design pattern is just an "introduction of abstraction layer"