diff --git a/command/pom.xml b/command/pom.xml
new file mode 100644
index 000000000..bd1471213
--- /dev/null
+++ b/command/pom.xml
@@ -0,0 +1,23 @@
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.0-SNAPSHOT
+
+ com.iluwatar
+ command
+ 1.0-SNAPSHOT
+ command
+ http://maven.apache.org
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
diff --git a/command/src/main/java/com/iluwatar/App.java b/command/src/main/java/com/iluwatar/App.java
new file mode 100644
index 000000000..5747a801f
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/App.java
@@ -0,0 +1,20 @@
+package com.iluwatar;
+
+public class App
+{
+ public static void main( String[] args )
+ {
+ Wizard wizard = new Wizard();
+ Goblin goblin = new Goblin();
+
+ goblin.printStatus();
+
+ wizard.castSpell(new ShrinkSpell(), goblin);
+ goblin.printStatus();
+
+ wizard.castSpell(new InvisibilitySpell(), goblin);
+ goblin.printStatus();
+ wizard.undoLastSpell();
+ goblin.printStatus();
+ }
+}
diff --git a/command/src/main/java/com/iluwatar/Command.java b/command/src/main/java/com/iluwatar/Command.java
new file mode 100644
index 000000000..e4f123029
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/Command.java
@@ -0,0 +1,12 @@
+package com.iluwatar;
+
+public abstract class Command {
+
+ public abstract void execute(Target target);
+
+ public abstract void undo();
+
+ @Override
+ public abstract String toString();
+
+}
diff --git a/command/src/main/java/com/iluwatar/Goblin.java b/command/src/main/java/com/iluwatar/Goblin.java
new file mode 100644
index 000000000..f8b161a54
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/Goblin.java
@@ -0,0 +1,15 @@
+package com.iluwatar;
+
+public class Goblin extends Target {
+
+ public Goblin() {
+ this.setSize(Size.NORMAL);
+ this.setVisibility(Visibility.VISIBLE);
+ }
+
+ @Override
+ public String toString() {
+ return "Goblin";
+ }
+
+}
diff --git a/command/src/main/java/com/iluwatar/InvisibilitySpell.java b/command/src/main/java/com/iluwatar/InvisibilitySpell.java
new file mode 100644
index 000000000..c21adce2d
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/InvisibilitySpell.java
@@ -0,0 +1,28 @@
+package com.iluwatar;
+
+public class InvisibilitySpell extends Command {
+
+ private Target target;
+
+ public InvisibilitySpell() {
+ target = null;
+ }
+
+ @Override
+ public void execute(Target target) {
+ target.setVisibility(Visibility.INVISIBLE);
+ this.target = target;
+ }
+
+ @Override
+ public void undo() {
+ if (target != null) {
+ target.setVisibility(Visibility.VISIBLE);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Invisibility spell";
+ }
+}
diff --git a/command/src/main/java/com/iluwatar/ShrinkSpell.java b/command/src/main/java/com/iluwatar/ShrinkSpell.java
new file mode 100644
index 000000000..b8dccc1d6
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/ShrinkSpell.java
@@ -0,0 +1,32 @@
+package com.iluwatar;
+
+public class ShrinkSpell extends Command {
+
+ private Size oldSize;
+
+ private Target target;
+
+ public ShrinkSpell() {
+ oldSize = null;
+ target = null;
+ }
+
+ @Override
+ public void execute(Target target) {
+ oldSize = target.getSize();
+ target.setSize(Size.SMALL);
+ this.target = target;
+ }
+
+ @Override
+ public void undo() {
+ if (oldSize != null && target != null) {
+ target.setSize(oldSize);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Shrink spell";
+ }
+}
diff --git a/command/src/main/java/com/iluwatar/Size.java b/command/src/main/java/com/iluwatar/Size.java
new file mode 100644
index 000000000..f55491085
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/Size.java
@@ -0,0 +1,31 @@
+package com.iluwatar;
+
+public enum Size {
+
+ SMALL,
+ NORMAL,
+ LARGE;
+
+ @Override
+ public String toString() {
+
+ String s = "";
+
+ switch (this) {
+ case LARGE:
+ s = "large";
+ break;
+ case NORMAL:
+ s = "normal";
+ break;
+ case SMALL:
+ s = "small";
+ break;
+ default:
+ break;
+ }
+ return s;
+ }
+
+
+}
diff --git a/command/src/main/java/com/iluwatar/Target.java b/command/src/main/java/com/iluwatar/Target.java
new file mode 100644
index 000000000..469d0187a
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/Target.java
@@ -0,0 +1,31 @@
+package com.iluwatar;
+
+public abstract class Target {
+
+ private Size size;
+
+ private Visibility visibility;
+
+ public Size getSize() {
+ return size;
+ }
+
+ public void setSize(Size size) {
+ this.size = size;
+ }
+
+ public Visibility getVisibility() {
+ return visibility;
+ }
+
+ public void setVisibility(Visibility visibility) {
+ this.visibility = visibility;
+ }
+
+ @Override
+ public abstract String toString();
+
+ public void printStatus() {
+ System.out.println(String.format("%s, size=%s visibility=%s", this, getSize(), getVisibility()));
+ }
+}
diff --git a/command/src/main/java/com/iluwatar/Visibility.java b/command/src/main/java/com/iluwatar/Visibility.java
new file mode 100644
index 000000000..5d2f3b974
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/Visibility.java
@@ -0,0 +1,26 @@
+package com.iluwatar;
+
+public enum Visibility {
+
+ VISIBLE,
+ INVISIBLE;
+
+ @Override
+ public String toString() {
+
+ String s = "";
+
+ switch (this) {
+ case INVISIBLE:
+ s = "invisible";
+ break;
+ case VISIBLE:
+ s = "visible";
+ break;
+ default:
+ break;
+
+ }
+ return s;
+ }
+}
diff --git a/command/src/main/java/com/iluwatar/Wizard.java b/command/src/main/java/com/iluwatar/Wizard.java
new file mode 100644
index 000000000..58d541bab
--- /dev/null
+++ b/command/src/main/java/com/iluwatar/Wizard.java
@@ -0,0 +1,31 @@
+package com.iluwatar;
+
+public class Wizard extends Target {
+
+ private Command previousSpell;
+
+ public Wizard() {
+ this.setSize(Size.NORMAL);
+ this.setVisibility(Visibility.VISIBLE);
+ previousSpell = null;
+ }
+
+ public void castSpell(Command command, Target target) {
+ System.out.println(this + " casts " + command + " at " + target);
+ command.execute(target);
+ previousSpell = command;
+ }
+
+ public void undoLastSpell() {
+ if (previousSpell != null) {
+ System.out.println(this + " undoes " + previousSpell);
+ previousSpell.undo();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Wizard";
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 7dba76b35..dcb498f7c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,7 @@
flyweight
proxy
chain
+ command