반응형
Notice
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- 인공지능
- 자료구조
- Yes
- 네트워크보안
- 컴퓨터과학
- 버전관리
- 데이터구조
- 보안
- 데이터분석
- 소프트웨어
- 네트워크
- 소프트웨어공학
- 빅데이터
- 파이썬
- 프로그래밍
- 디자인패턴
- 프로그래밍언어
- 클라우드컴퓨팅
- I'm Sorry
- 데이터베이스
- 알고리즘
- 자바스크립트
- 데이터과학
- 사이버보안
- 딥러닝
- springboot
- 웹개발
- 컴퓨터공학
- 머신러닝
- 컴퓨터비전
Archives
- Today
- Total
스택큐힙리스트
명령을 객체로! 커맨드 패턴으로 유연한 실행 로직 만들기 🚀 본문
반응형
왜 또 커맨드 패턴인가?
버튼 하나에 기능을 자꾸 갈아끼워야 할 때마다 if-else 덩어리를 늘리는 대신, “명령 자체를 객체로 포장”하면 된다. 요청(함수 이름·인자·수행 시점)을 통째로 캡슐화해 큐에 쌓거나, 로그로 남기거나, 실행 ↔ 취소까지 자유자재로 다룰 수 있다는 얘기다. 국내 인기 블로그들도 “요청을 객체로 만들어 느슨한 결합을 얻는다”는 점을 1순위 장점으로 꼽는다.
패턴 한 줄 정의
Invoker(요청자)가 Command(명령 객체)를 실행하면, 명령은 Receiver(실제 작업자)에게 일을 시킨다.
Invoker는 “누가 어떻게 일하느냐”에 전혀 관여하지 않는다. 때문에 실행 시점 지연, 일괄 처리, undo/redo, 트랜잭션 롤백 같은 고급 기능을 끼워 넣기 쉽다.
핵심 구성 요소
- Command 인터페이스: execute()·undo() 같은 동작 규약
- ConcreteCommand: 실제 로직과 Receiver 참조 보관
- Receiver: 명령을 수행할 도메인 객체
- Invoker: 명령을 받아 실행·취소·재실행 등 타이밍 제어
- Client: 누가 어떤 ConcreteCommand를 Invoker에 심을지 결정
코틀린 예제 – 리모컨 & 가전
// Command
fun interface Command { fun execute() }
// Receiver
class Light {
fun on() = println("💡 불 켜짐")
fun off() = println("💡 불 꺼짐")
}
// ConcreteCommand
class LightOnCommand(private val light: Light) : Command {
override fun execute() = light.on()
}
// Invoker
class RemoteControl {
private val slots = mutableMapOf<Int, Command>()
fun setCommand(slot: Int, cmd: Command) { slots[slot] = cmd }
fun press(slot: Int) = slots[slot]?.execute()
}
// 사용
fun main() {
val light = Light()
val remote = RemoteControl()
remote.setCommand(0, LightOnCommand(light))
remote.press(0) // 💡 불 켜짐
}
명령이 객체이므로 remote.setCommand()만으로 버튼 역할을 핫스왑할 수 있다. undo()를 추가해 실행 내역 스택을 관리하면 스마트홈 앱에서도 그대로 쓸 수 있다.
실전에서 빛나는 순간
- Undo / Redo: 포토샵, IDE 단축키
- 매크로·배치 작업: 여러 명령을 List로 묶어 한 번에 실행
- CQRS/이벤트 소싱: “쓰기 명령(Command) vs 읽기(Query)” 분리 구조의 근간
- 스프링 부트: ApplicationRunner, CommandLineRunner가 대표적인 Command 구현체다.
장점 🔥
- 요청, 실행 시점을 분리해 스케줄링·트랜잭션 재시도가 간단
- OCP 준수: 새 명령 클래스만 만들면 Invoker 수정 없음
- 로깅·모니터링이 쉬워 운영 관점에서도 유리
주의할 점 ⚠️
- 명령 종류가 폭증하면 클래스 수도 급격히 늘어난다.
- 간단한 호출이면 람다 전달이 더 짧고 명료할 때도 있다.
반응형
'개발' 카테고리의 다른 글
책임 연쇄 vs 데코레이터 — 헷갈리는 두 패턴, 결정적 차이를 콕 짚다 (1) | 2025.07.28 |
---|---|
책임을 넘겨라! Chain of Responsibility 한방 정복 (2) | 2025.07.28 |
Factory Method vs Template Method ― “누가 만들고, 누가 조립하나?” (3) | 2025.07.24 |
명령을 객체로! 커맨드 패턴으로 유연한 실행 로직 만들기 🚀 (1) | 2025.07.23 |
프론트엔드와 API 통합 테스트 전략 (2) | 2025.07.23 |
Comments