diff --git a/.idea/misc.xml b/.idea/misc.xml
index cb58576..cd6d678 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="ProjectRootManager" version="2" project-jdk-name="11" project-jdk-type="JavaSDK">
+  <component name="PWA">
+    <option name="enabled" value="true" />
+    <option name="wasEnabledAtLeastOnce" value="true" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
   </component>
   <component name="ProjectType">
diff --git a/.idea/sonarlint/issuestore/index.pb b/.idea/sonarlint/issuestore/index.pb
index 73a5180..e69de29 100644
--- a/.idea/sonarlint/issuestore/index.pb
+++ b/.idea/sonarlint/issuestore/index.pb
@@ -1,36 +0,0 @@
-
-A
-DesignPattern.iml,d/d/ddc9a374972c7483f5deb79100ddf778f94c1496
-V
-&src/strategy/behavior/FlyBehavior.java,e/c/ec415734764b2dedccd89ba4a70e4d6efc7066a7
-X
-(src/strategy/behavior/impl/FlyNoWay.java,7/8/78bee654a203485eb58e6d1d94e67ac4e51dbe0d
-`
-0src/strategy/behavior/impl/FlyRocketPowered.java,0/2/02a098faf95330118f0960668634aea19612928f
-Y
-)src/strategy/behavior/impl/LoudQuack.java,f/1/f185a139752e3298524f4ef1874c578621db7d60
-S
-#src/strategy/ducks/MallardDuck.java,1/4/14f6317fc8bc94e327ccd406a7b03f8935cb79ac
-L
-src/strategy/전략패턴.md,5/f/5f7bfc03ce3acf6e0d10a3882812dca2c69e725a
-:
-
-.gitignore,a/5/a5cc2925ca8258af241be7e5b0381edf30266302
-Y
-)src/observer/observer/DisplayElement.java,f/c/fca96fae5c78b096008b30eabf7cd82e7ad5d882
-9
-	README.md,8/e/8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d
-Q
-!src/observer/subject/Subject.java,c/3/c32a2be715e209e5a0551fb5b479641ce32916e3
-K
-src/strategy/base/Duck.java,1/c/1c420d85031fcdbd88fa82a2f108f62f89f63eab
-X
-(src/strategy/behavior/QuackBehavior.java,d/8/d80b82ba203166acb34ef1978ee328c59c31fc01
-Y
-)src/strategy/behavior/impl/MuteQuack.java,b/d/bdbfa0c0c70fd53bd1379edc92d465258514fce0
-\
-,src/strategy/behavior/impl/FlyWithWings.java,d/b/db84418fc6f4db857ab779c91a124176eea01f9a
-P
- src/strategy/ducks/MuteDuck.java,4/d/4d4c5927c6233fcb16c3328f972d6f6cd6f23c27
-Q
-!src/strategy/StrategyPattern.java,d/3/d30eb9a4f19ee8cf5ce5fd75a8f8857424d8287c
\ No newline at end of file
diff --git a/img/command/img.png b/img/command/img.png
new file mode 100644
index 0000000..ff8bf7f
Binary files /dev/null and b/img/command/img.png differ
diff --git a/img/command/img2.png b/img/command/img2.png
new file mode 100644
index 0000000..29804ab
Binary files /dev/null and b/img/command/img2.png differ
diff --git a/img/command/img3.png b/img/command/img3.png
new file mode 100644
index 0000000..9d7aaa7
Binary files /dev/null and b/img/command/img3.png differ
diff --git a/src/command/CommandPattern.java b/src/command/CommandPattern.java
new file mode 100644
index 0000000..49ede06
--- /dev/null
+++ b/src/command/CommandPattern.java
@@ -0,0 +1,112 @@
+package command;
+
+import command.command.impl.*;
+import command.invoker.RemoteControl;
+import command.invoker.RemoteControlWithUndo;
+import command.invoker.SimpleRemoteControl;
+import command.receiver.GarageDoor;
+import command.receiver.Light;
+import command.receiver.Stereo;
+
+/**
+ * 커맨드 패턴에서 클라이언트에 해당하는 클래스
+ */
+public class CommandPattern {
+    public static void main(String[] args) {
+//        simpleRemoteControl();
+//        remoteControl();
+        remoteControlWithUndo();
+    }
+
+    private static void simpleRemoteControl() {
+        final SimpleRemoteControl remote = new SimpleRemoteControl(); // remote 변수 : 인보커(invoker)
+
+        final Light light = new Light(); // light : 리시버
+        final LightOnCommand lightOnCommand = new LightOnCommand(light); // lightOnCommand : 커맨드 객체
+
+        final GarageDoor garageDoor = new GarageDoor(); // 리시버
+        final GarageDoorUpCommand garageDoorUpCommand = new GarageDoorUpCommand(garageDoor); // 커맨드 객체
+
+        remote.setCommand(lightOnCommand); // invoker의 setCommand 메소드로 커맨드 객체를 전달
+        remote.buttonWasPressed(); // invoker로 커맨드 객체의 execute 메소드를 호출
+
+        remote.setCommand(garageDoorUpCommand);
+        remote.buttonWasPressed();
+    }
+
+    private static void remoteControl() {
+        RemoteControl remoteControl = new RemoteControl();
+
+        Light livingRoomLight = new Light("Living Room");
+        Light kitchenLight = new Light("Kitchen");
+        GarageDoor garageDoor = new GarageDoor("Garage");
+        Stereo livingRoomStereo = new Stereo("Living Room");
+
+        LightOnCommand livingRoomLightOnCommand = new LightOnCommand(livingRoomLight);
+        LightOffCommand livingRoomLightOffCommand = new LightOffCommand(livingRoomLight);
+        LightOnCommand kitchenLightOnCommand = new LightOnCommand(kitchenLight);
+        LightOffCommand kitchenLightOffCommand = new LightOffCommand(kitchenLight);
+        GarageDoorUpCommand garageDoorUpCommand = new GarageDoorUpCommand(garageDoor);
+        GarageDoorDownCommand garageDoorDownCommand = new GarageDoorDownCommand(garageDoor);
+        StereoOnWithCDCommand stereoOnWithCDCommand = new StereoOnWithCDCommand(livingRoomStereo);
+        StereoOffCommand stereoOffCommand = new StereoOffCommand(livingRoomStereo);
+
+        remoteControl.setCommand(0, livingRoomLightOnCommand, livingRoomLightOffCommand);
+        remoteControl.setCommand(1, kitchenLightOnCommand, kitchenLightOffCommand);
+        remoteControl.setCommand(2, garageDoorUpCommand, garageDoorDownCommand);
+        remoteControl.setCommand(3, stereoOnWithCDCommand, stereoOffCommand);
+
+        System.out.println(remoteControl);
+
+        for (int i = 0; i < 4; i++) {
+            remoteControl.onButtonWasPushed(i);
+            remoteControl.offButtonWasPushed(i);
+        }
+    }
+
+    private static void remoteControlWithLambda() {
+        RemoteControl remoteControl = new RemoteControl();
+
+        Light livingRoomLight = new Light("Living Room");
+        Light kitchenLight = new Light("Kitchen");
+        GarageDoor garageDoor = new GarageDoor("Garage");
+        Stereo livingRoomStereo = new Stereo("Living Room");
+
+        StereoOnWithCDCommand stereoOnWithCDCommand = new StereoOnWithCDCommand(livingRoomStereo);
+        StereoOffCommand stereoOffCommand = new StereoOffCommand(livingRoomStereo);
+
+        // 람다식은 메소드가 오직 한개일 때에만 사용할 수 있다.
+//        remoteControl.setCommand(0, livingRoomLight::on, livingRoomLight::off);
+//        remoteControl.setCommand(1, kitchenLight::on, kitchenLight::off);
+//        remoteControl.setCommand(2, garageDoor::up, garageDoor::down);
+        remoteControl.setCommand(3, stereoOnWithCDCommand, stereoOffCommand);
+
+        System.out.println(remoteControl);
+
+        for (int i = 0; i < 4; i++) {
+            remoteControl.onButtonWasPushed(i);
+            remoteControl.offButtonWasPushed(i);
+        }
+    }
+
+    private static void remoteControlWithUndo() {
+        RemoteControlWithUndo remoteControl = new RemoteControlWithUndo();
+
+        Light livingRoomLight = new Light("Living Room");
+
+        LightOnCommand livingRoomLightOnCommand = new LightOnCommand(livingRoomLight);
+        LightOffCommand livingRoomLightOffCommand = new LightOffCommand(livingRoomLight);
+
+        remoteControl.setCommand(0, livingRoomLightOnCommand, livingRoomLightOffCommand);
+
+        remoteControl.onButtonWasPushed(0);
+        remoteControl.offButtonWasPushed(0);
+        System.out.println(remoteControl);
+
+        remoteControl.undoButtonWasPushed();
+
+        remoteControl.offButtonWasPushed(0);
+        remoteControl.onButtonWasPushed(0);
+        System.out.println(remoteControl);
+    }
+}
diff --git a/src/command/command/Command.java b/src/command/command/Command.java
new file mode 100644
index 0000000..61b4130
--- /dev/null
+++ b/src/command/command/Command.java
@@ -0,0 +1,11 @@
+package command.command;
+
+/**
+ * 커맨드 객체는 모두 같은 인터페이스(Command)를 구현해야 한다.
+ * 해당 인터페이스는 메소드가 하나뿐이다.
+ */
+public interface Command {
+    void execute();
+
+    void undo();
+}
diff --git a/src/command/command/impl/GarageDoorDownCommand.java b/src/command/command/impl/GarageDoorDownCommand.java
new file mode 100644
index 0000000..ecf7664
--- /dev/null
+++ b/src/command/command/impl/GarageDoorDownCommand.java
@@ -0,0 +1,22 @@
+package command.command.impl;
+
+import command.command.Command;
+import command.receiver.GarageDoor;
+
+public class GarageDoorDownCommand implements Command {
+    private final GarageDoor garageDoor;
+
+    public GarageDoorDownCommand(GarageDoor garageDoor) {
+        this.garageDoor = garageDoor;
+    }
+
+    @Override
+    public void execute() {
+        garageDoor.down();
+    }
+
+    @Override
+    public void undo() {
+        garageDoor.up();
+    }
+}
diff --git a/src/command/command/impl/GarageDoorUpCommand.java b/src/command/command/impl/GarageDoorUpCommand.java
new file mode 100644
index 0000000..8e1247a
--- /dev/null
+++ b/src/command/command/impl/GarageDoorUpCommand.java
@@ -0,0 +1,22 @@
+package command.command.impl;
+
+import command.command.Command;
+import command.receiver.GarageDoor;
+
+public class GarageDoorUpCommand implements Command {
+    private final GarageDoor garageDoor;
+
+    public GarageDoorUpCommand(GarageDoor garageDoor) {
+        this.garageDoor = garageDoor;
+    }
+
+    @Override
+    public void execute() {
+        garageDoor.up();
+    }
+
+    @Override
+    public void undo() {
+        garageDoor.down();
+    }
+}
diff --git a/src/command/command/impl/LightOffCommand.java b/src/command/command/impl/LightOffCommand.java
new file mode 100644
index 0000000..f0666e7
--- /dev/null
+++ b/src/command/command/impl/LightOffCommand.java
@@ -0,0 +1,22 @@
+package command.command.impl;
+
+import command.command.Command;
+import command.receiver.Light;
+
+public class LightOffCommand implements Command {
+    private final Light light; // 리시버 객체
+
+    public LightOffCommand(Light light) {
+        this.light = light;
+    }
+
+    @Override
+    public void execute() {
+        light.off();
+    }
+
+    @Override
+    public void undo() {
+        light.on();
+    }
+}
diff --git a/src/command/command/impl/LightOnCommand.java b/src/command/command/impl/LightOnCommand.java
new file mode 100644
index 0000000..e5c10b5
--- /dev/null
+++ b/src/command/command/impl/LightOnCommand.java
@@ -0,0 +1,22 @@
+package command.command.impl;
+
+import command.command.Command;
+import command.receiver.Light;
+
+public class LightOnCommand implements Command {
+    private final Light light; // 리시버 객체
+
+    public LightOnCommand(Light light) {
+        this.light = light;
+    }
+
+    @Override
+    public void execute() {
+        light.on();
+    }
+
+    @Override
+    public void undo() {
+        light.off();
+    }
+}
diff --git a/src/command/command/impl/NoCommand.java b/src/command/command/impl/NoCommand.java
new file mode 100644
index 0000000..d9aaf42
--- /dev/null
+++ b/src/command/command/impl/NoCommand.java
@@ -0,0 +1,20 @@
+package command.command.impl;
+
+import command.command.Command;
+
+/**
+ * 일종의 null object
+ * null 처리 로직을 줄이고 싶을 때 활용한다.
+ * null object 를 일종의 디자인 패턴으로 분류하기도 한다.
+ */
+public class NoCommand implements Command {
+    @Override
+    public void execute() {
+
+    }
+
+    @Override
+    public void undo() {
+
+    }
+}
diff --git a/src/command/command/impl/StereoOffCommand.java b/src/command/command/impl/StereoOffCommand.java
new file mode 100644
index 0000000..d3ea730
--- /dev/null
+++ b/src/command/command/impl/StereoOffCommand.java
@@ -0,0 +1,24 @@
+package command.command.impl;
+
+import command.command.Command;
+import command.receiver.Stereo;
+
+public class StereoOffCommand implements Command {
+    private final Stereo stereo;
+
+    public StereoOffCommand(Stereo stereo) {
+        this.stereo = stereo;
+    }
+
+    @Override
+    public void execute() {
+        stereo.off();
+    }
+
+    @Override
+    public void undo() {
+        stereo.on();
+        stereo.setCD();
+        stereo.setVolume(11);
+    }
+}
diff --git a/src/command/command/impl/StereoOnWithCDCommand.java b/src/command/command/impl/StereoOnWithCDCommand.java
new file mode 100644
index 0000000..0efc7cc
--- /dev/null
+++ b/src/command/command/impl/StereoOnWithCDCommand.java
@@ -0,0 +1,24 @@
+package command.command.impl;
+
+import command.command.Command;
+import command.receiver.Stereo;
+
+public class StereoOnWithCDCommand implements Command {
+    private final Stereo stereo;
+
+    public StereoOnWithCDCommand(Stereo stereo) {
+        this.stereo = stereo;
+    }
+
+    @Override
+    public void execute() {
+        stereo.on();
+        stereo.setCD();
+        stereo.setVolume(11);
+    }
+
+    @Override
+    public void undo() {
+        stereo.off();
+    }
+}
diff --git a/src/command/invoker/RemoteControl.java b/src/command/invoker/RemoteControl.java
new file mode 100644
index 0000000..3a7e185
--- /dev/null
+++ b/src/command/invoker/RemoteControl.java
@@ -0,0 +1,49 @@
+package command.invoker;
+
+import command.command.Command;
+import command.command.impl.NoCommand;
+
+public class RemoteControl {
+    Command[] onCommands;
+    Command[] offCommands;
+
+    public RemoteControl() {
+        onCommands = new Command[7];
+        offCommands = new Command[7];
+
+        final NoCommand noCommand = new NoCommand(); // 빈 커맨드 객체
+        for (int i = 0; i < 7; i++) {
+            onCommands[i] = noCommand;
+            offCommands[i] = noCommand;
+        }
+    }
+
+    public void setCommand(int slot, Command onCommand, Command offCommand) {
+        onCommands[slot] = onCommand;
+        offCommands[slot] = offCommand;
+    }
+
+    public void onButtonWasPushed(int slot) {
+        onCommands[slot].execute();
+    }
+
+    public void offButtonWasPushed(int slot) {
+        offCommands[slot].execute();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("\n------- 리모컨 -------\n");
+        for (int i = 0; i < onCommands.length; i++) {
+            stringBuilder.append("[slot ")
+                    .append(i)
+                    .append("]")
+                    .append(onCommands[i].getClass().getName())
+                    .append("   ")
+                    .append(offCommands[i].getClass().getName())
+                    .append("\n");
+        }
+        return stringBuilder.toString();
+    }
+}
diff --git a/src/command/invoker/RemoteControlWithUndo.java b/src/command/invoker/RemoteControlWithUndo.java
new file mode 100644
index 0000000..3cdeb80
--- /dev/null
+++ b/src/command/invoker/RemoteControlWithUndo.java
@@ -0,0 +1,60 @@
+package command.invoker;
+
+import command.command.Command;
+import command.command.impl.NoCommand;
+
+public class RemoteControlWithUndo {
+    Command[] onCommands;
+    Command[] offCommands;
+    Command undoCommand;
+
+    public RemoteControlWithUndo() {
+        onCommands = new Command[7];
+        offCommands = new Command[7];
+
+        final NoCommand noCommand = new NoCommand(); // 빈 커맨드 객체
+        for (int i = 0; i < 7; i++) {
+            onCommands[i] = noCommand;
+            offCommands[i] = noCommand;
+        }
+        undoCommand = noCommand;
+    }
+
+    public void setCommand(int slot, Command onCommand, Command offCommand) {
+        onCommands[slot] = onCommand;
+        offCommands[slot] = offCommand;
+    }
+
+    public void onButtonWasPushed(int slot) {
+        onCommands[slot].execute();
+        undoCommand = onCommands[slot];
+    }
+
+    public void offButtonWasPushed(int slot) {
+        offCommands[slot].execute();
+        undoCommand = offCommands[slot];
+    }
+
+    public void undoButtonWasPushed() {
+        undoCommand.undo();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("\n------- 리모컨 -------\n");
+        for (int i = 0; i < onCommands.length; i++) {
+            stringBuilder.append("[slot ")
+                    .append(i)
+                    .append("]")
+                    .append(onCommands[i].getClass().getSimpleName())
+                    .append("   ")
+                    .append(offCommands[i].getClass().getSimpleName())
+                    .append("\n");
+        }
+        stringBuilder.append("[undo] ")
+                .append(undoCommand.getClass().getSimpleName())
+                .append("\n");
+        return stringBuilder.toString();
+    }
+}
diff --git a/src/command/invoker/SimpleRemoteControl.java b/src/command/invoker/SimpleRemoteControl.java
new file mode 100644
index 0000000..8c840e9
--- /dev/null
+++ b/src/command/invoker/SimpleRemoteControl.java
@@ -0,0 +1,23 @@
+package command.invoker;
+
+import command.command.Command;
+
+public class SimpleRemoteControl {
+    Command slot;
+
+    public SimpleRemoteControl() {
+    }
+
+    /**
+     * 커맨드 객체로 제어할 명령을 설정하는 메소드
+     *
+     * @param command
+     */
+    public void setCommand(Command command) {
+        slot = command;
+    }
+
+    public void buttonWasPressed() {
+        slot.execute();
+    }
+}
diff --git a/src/command/receiver/GarageDoor.java b/src/command/receiver/GarageDoor.java
new file mode 100644
index 0000000..2f4e4a3
--- /dev/null
+++ b/src/command/receiver/GarageDoor.java
@@ -0,0 +1,20 @@
+package command.receiver;
+
+public class GarageDoor {
+    private String location = "";
+
+    public GarageDoor() {
+    }
+
+    public GarageDoor(String location) {
+        this.location = location;
+    }
+
+    public void up() {
+        System.out.println(location + " garage up");
+    }
+
+    public void down() {
+        System.out.println(location + " garage down");
+    }
+}
diff --git a/src/command/receiver/Light.java b/src/command/receiver/Light.java
new file mode 100644
index 0000000..a89359a
--- /dev/null
+++ b/src/command/receiver/Light.java
@@ -0,0 +1,20 @@
+package command.receiver;
+
+public class Light {
+    private String location = "";
+
+    public Light() {
+    }
+
+    public Light(String location) {
+        this.location = location;
+    }
+
+    public void on() {
+        System.out.println(location + " light on");
+    }
+
+    public void off() {
+        System.out.println(location + " light off");
+    }
+}
diff --git a/src/command/receiver/Stereo.java b/src/command/receiver/Stereo.java
new file mode 100644
index 0000000..3f2583c
--- /dev/null
+++ b/src/command/receiver/Stereo.java
@@ -0,0 +1,28 @@
+package command.receiver;
+
+public class Stereo {
+    private String location = "";
+
+    public Stereo() {
+    }
+
+    public Stereo(String location) {
+        this.location = location;
+    }
+
+    public void on() {
+        System.out.println(location + " stereo on");
+    }
+
+    public void setCD() {
+        System.out.println(location + " set cd");
+    }
+
+    public void setVolume(int i) {
+        System.out.println(location + " set volume: " + i);
+    }
+
+    public void off() {
+        System.out.println(location + " stereo off");
+    }
+}
diff --git "a/src/command/\354\273\244\353\247\250\353\223\234 \355\214\250\355\204\264.md" "b/src/command/\354\273\244\353\247\250\353\223\234 \355\214\250\355\204\264.md"
new file mode 100644
index 0000000..02eb9e8
--- /dev/null
+++ "b/src/command/\354\273\244\353\247\250\353\223\234 \355\214\250\355\204\264.md"	
@@ -0,0 +1,37 @@
+# 커맨드 패턴
+
+- 작업을 요청하는 쪽과 작업을 처리하는 쪽을 분리할 수 있도록 하는 디자인 패턴
+- 커맨드 객체를 통해 특정 객체에 관한 특정 작업 요청을 캡슐화할 수 있다 -> 구체적으로 어떤 작업을 해야하는지에 대해 아는 것은 커맨드 객체이다.
+- 커맨드 패턴을 사용하면, 요청 내역을 객체로 캡슐화하여 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있다. -> 요청을 큐에 저장하거나 로그로 기록하거나 작업 취소 기능을 사용할 수 있다.
+
+> 구체적인 커맨드 패턴의 예시
+
+![img.png](../../img/command/img.png)
+
+![img.png](../../img/command/img2.png)
+
+1. createCommandObject() : 클라이언트가 리시버에 전달할 일련의 행동으로 구성된 커맨드 객체를 생성</br>execute() : 커맨드 객체의 유일한 execute() 메소드로 행동을 캡슐화하여
+   리시버의 특정 행동을 처리
+2. setCommand() : 클라이언트는 인보커 객체의 setCommand() 메소드를 호출하므로써 커맨드 객체를 넘겨줌
+3. execute() -> action() : 인보커에서 커맨드 객체의 execute() 메소드를 호출하면 -> 리시버의 특정 행동 메소드가 호출됨
+
+|    커맨드 패턴    |   식당    |
+|:------------:|:-------:|
+|   클라이언트 객체   |   고객    |
+|    커맨드 객체    |   주문서   |
+|    인보커 객체    |   종업원   |
+| setCommand() | 주문 수행하기 |
+|  execute()   |  주분 받기  |
+|    리시버 객체    |   주방장   |
+
+# 커맨드 패턴의 적용 예시
+
+커맨드 패턴은 스케쥴러, 스레드 풀, 작업 큐 등과 같은 다양한 작업에 적용할 수 있다.
+
+- 작업 큐에 쌓인 여러 작업(커맨드 객체)들의 execute() 메소드를 호출
+
+![img.png](../../img/command/img3.png)
+
+애플리케이션이 비정상 종료되었을 때, 이전의 행동을 복구하는데에 커맨드 패턴을 활용할 수 있다
+
+- store(), load() 메소드를 커맨드 객체에 추가하여 구현할 수 있다
