/ DESIGN-PATTERN

커맨드 패턴 - Command Pattern [디자인패턴/코틀린/kotlin]

커맨드 패턴은 각각 형태가 다른 메소드를 추상화하여 클라이언트가 사용할 수 있도록 하는 패턴

커맨드 패턴 - Command Pattern

커맨드 패턴이란

커맨드 패턴은 각각 형태가 다른 메소드를 추상화하여 클라이언트가 사용할 수 있도록 하는 패턴

이해를 돕기 위한 설명

커맨트패턴 미적용

운전(타입)
    if (타입 == 오토바이)
        오토바이 오토바이 = 오토바이()
        오토바이.시동()
        오토바이.가속핸들돌린다()
    else if (타입 == 자전거)
        자전거 자전거 = 자전거()
        자전거.페달을밟는다()
    ...        
  • 두종류의 이동 수단은 조작 하는 방법이 서로다르다
  • 오토바이는 시동을 건다, 가속핸들을 돌린다, 자전거는 페달을 밟는다.
  • 각 탈것 종류에 따라 운전하는 방법을 분기처리한다.
  • 탈 것이 추가 되면 코드 수정이 필요하다.

커맨트 패턴 적용

운전(배달명령)
    배달명령.탈것운전()
  • 여러 탈것을 운전하는 행위를 탈것운전()이라는 메소드를 추상화 하여 클라이언트에게 제공한다.
  • 클라이언트는 배달명령이라는 일련의 메소드가 추상화된 배달명령의 탈것운전() 메소드만 사용한다.
  • 탈 것 종류가 추가 되어도 코드 변경은 없다.

장점

  • 기존 Code를 수정하지 않고, 새 명령을 쉽게 추가할 수 있다
  • 명령의 호출자와 수신자의 의존성을 제거한다.

단점

  • 명령에 대한 클래스가 늘어난다.

클래스 다이어그램

class-diagram

예제코드

오토바이/자전거 클래스

class MotorCycle {
    fun start() = "오토바이시동"
    fun accelerate() = "오토바이출발"
}

class Bike {
    fun pedaling() = "자전거출발"
}

명령 메소드를 추상화

interface DeliveryCommand {
    fun driveVehicle(): String
}

class MotorCycleCommand(private var motorCycle: MotorCycle) : DeliveryCommand {
    override fun driveVehicle() =
            motorCycle.start() + motorCycle.accelerate()
}

class BikeCommand : DeliveryCommand {
    override fun driveVehicle() = bike.pedaling()
}

클라이언트

class Rider(private var deliveryCommand: DeliveryCommand) {
    fun changeDeliveryCommand(deliveryCommand: DeliveryCommand): Rider {
        this.deliveryCommand = deliveryCommand
        return this
    }

    fun delivery() = deliveryCommand.driveVehicle()
}

val motorCycleCommand = MotorCycleCommand(MotorCycle())
val bikeCommand = BikeCommand(Bike())

val rider = Rider(motorCycleCommand)

// 오토바이를 운전한다.
rider.delivery()
// 자전거로 변경한다.
rider.changeDeliveryCommand(bikeCommand)
// 자전거를 운전한다.
rider.delivery()

라이더 클라이언트는 분기문 없이 일관성있는 코드를 사용하며 로직변경이나 탈것의 추가에도 코드 수정에서 자유롭다.

kimchanjung

김찬정

좀 더 넓은 TEST 커버리지! 좀 더 나은 Architecture! 좀 더 나은 Code Pattern! 보다 더 간결하고 깔끔한 코드!를 항상 갈망 합니다.

Read More