diff --git a/src/state/StatePattern.java b/src/state/StatePattern.java
new file mode 100644
index 0000000..0f366ab
--- /dev/null
+++ b/src/state/StatePattern.java
@@ -0,0 +1,19 @@
+package state;
+
+import state.context.GumballMachine;
+
+public class StatePattern {
+    public static void main(String[] args) {
+        GumballMachine gumballMachine = new GumballMachine(5);
+
+        for (int i = 0; i < 10; i++) {
+            System.out.println(gumballMachine);
+            gumballMachine.insertQuarter();
+            gumballMachine.turnCrank();
+            if (gumballMachine.getCount() == 0) {
+                gumballMachine.refill(10);
+            }
+        }
+
+    }
+}
diff --git a/src/state/context/GumballMachine.java b/src/state/context/GumballMachine.java
new file mode 100644
index 0000000..39ba22e
--- /dev/null
+++ b/src/state/context/GumballMachine.java
@@ -0,0 +1,95 @@
+package state.context;
+
+import state.state.State;
+import state.state.impl.*;
+
+public class GumballMachine {
+
+    private final State soldOut;
+    private final State noQuarter;
+    private final State hasQuarter;
+    private final State sold;
+    private final State winner;
+    private State state;
+    private int count = 0;
+
+    public GumballMachine(int numberGumballs) {
+        soldOut = new SoldOutState(this);
+        noQuarter = new NoQuarterState(this);
+        hasQuarter = new HasQuarterState(this);
+        sold = new SoldState(this);
+        winner = new WinnerState(this);
+        this.count = numberGumballs;
+        if (numberGumballs > 0) {
+            state = noQuarter;
+        } else {
+            state = soldOut;
+        }
+    }
+
+    public void insertQuarter() {
+        state.insertQuarter();
+    }
+
+    public void ejectQuarter() {
+        state.ejectQuarter();
+    }
+
+    public void turnCrank() {
+        state.turnCrank();
+        state.dispense();
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    public void releaseBall() {
+        System.out.println("알맹이를 내보내고 있습니다");
+        if (count > 0) {
+            count--;
+        }
+    }
+
+    public void refill(int count) {
+        this.count += count;
+        System.out.println("리필 되었습니다. count=" + this.count);
+        state.refill(count);
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public State getSoldOut() {
+        return soldOut;
+    }
+
+    public State getNoQuarter() {
+        return noQuarter;
+    }
+
+    public State getHasQuarter() {
+        return hasQuarter;
+    }
+
+    public State getSold() {
+        return sold;
+    }
+
+    public State getWinner() {
+        return winner;
+    }
+
+    @Override
+    public String toString() {
+        return "GumballMachine{" +
+                "state=" + state.getClass().getSimpleName() +
+                ", count=" + count +
+                '}';
+    }
+}
diff --git a/src/state/state/State.java b/src/state/state/State.java
new file mode 100644
index 0000000..6da30b1
--- /dev/null
+++ b/src/state/state/State.java
@@ -0,0 +1,15 @@
+package state.state;
+
+public interface State {
+    void insertQuarter();
+
+    void ejectQuarter();
+
+    void turnCrank();
+
+    void dispense();
+
+    default void refill(int count) {
+        System.out.println("알맹이가 매진되지 않았습니다");
+    }
+}
diff --git a/src/state/state/impl/HasQuarterState.java b/src/state/state/impl/HasQuarterState.java
new file mode 100644
index 0000000..ce4840e
--- /dev/null
+++ b/src/state/state/impl/HasQuarterState.java
@@ -0,0 +1,42 @@
+package state.state.impl;
+
+import state.context.GumballMachine;
+import state.state.State;
+
+import java.util.Random;
+
+public class HasQuarterState implements State {
+    private final Random random = new Random(System.currentTimeMillis());
+    private final GumballMachine gumballMachine;
+
+    public HasQuarterState(GumballMachine gumballMachine) {
+        this.gumballMachine = gumballMachine;
+    }
+
+    @Override
+    public void insertQuarter() {
+        System.out.println("동전을 한 개만 넣어주세요");
+    }
+
+    @Override
+    public void ejectQuarter() {
+        System.out.println("동전이 반환됩니다.");
+        gumballMachine.setState(gumballMachine.getNoQuarter());
+    }
+
+    @Override
+    public void turnCrank() {
+        System.out.println("손잡이를 돌리셨습니다");
+        int winner = random.nextInt(10);
+        if (winner == 0 && gumballMachine.getCount() > 1) {
+            gumballMachine.setState(gumballMachine.getWinner());
+        } else {
+            gumballMachine.setState(gumballMachine.getSold());
+        }
+    }
+
+    @Override
+    public void dispense() {
+        System.out.println("알맹이를 내보낼 수 없습니다");
+    }
+}
diff --git a/src/state/state/impl/NoQuarterState.java b/src/state/state/impl/NoQuarterState.java
new file mode 100644
index 0000000..e828f5e
--- /dev/null
+++ b/src/state/state/impl/NoQuarterState.java
@@ -0,0 +1,33 @@
+package state.state.impl;
+
+import state.context.GumballMachine;
+import state.state.State;
+
+public class NoQuarterState implements State {
+    private final GumballMachine gumballMachine;
+
+    public NoQuarterState(GumballMachine gumballMachine) {
+        this.gumballMachine = gumballMachine;
+    }
+
+    @Override
+    public void insertQuarter() {
+        System.out.println("동전을 넣음");
+        gumballMachine.setState(gumballMachine.getHasQuarter());
+    }
+
+    @Override
+    public void ejectQuarter() {
+        System.out.println("동전을 넣어 주세요");
+    }
+
+    @Override
+    public void turnCrank() {
+        System.out.println("동전을 넣어 주세요");
+    }
+
+    @Override
+    public void dispense() {
+        System.out.println("동전을 넣어 주세요");
+    }
+}
diff --git a/src/state/state/impl/SoldOutState.java b/src/state/state/impl/SoldOutState.java
new file mode 100644
index 0000000..24a2786
--- /dev/null
+++ b/src/state/state/impl/SoldOutState.java
@@ -0,0 +1,37 @@
+package state.state.impl;
+
+import state.context.GumballMachine;
+import state.state.State;
+
+public class SoldOutState implements State {
+    private final GumballMachine gumballMachine;
+
+    public SoldOutState(GumballMachine gumballMachine) {
+        this.gumballMachine = gumballMachine;
+    }
+
+    @Override
+    public void insertQuarter() {
+        System.out.println("매진 되었습니다");
+    }
+
+    @Override
+    public void ejectQuarter() {
+        System.out.println("매진 되었습니다");
+    }
+
+    @Override
+    public void turnCrank() {
+        System.out.println("매진 되었습니다");
+    }
+
+    @Override
+    public void dispense() {
+        System.out.println("매진 되었습니다. 알맹이를 내보낼 수 없습니다");
+    }
+
+    @Override
+    public void refill(int count) {
+        gumballMachine.setState(gumballMachine.getNoQuarter());
+    }
+}
diff --git a/src/state/state/impl/SoldState.java b/src/state/state/impl/SoldState.java
new file mode 100644
index 0000000..0cd9955
--- /dev/null
+++ b/src/state/state/impl/SoldState.java
@@ -0,0 +1,40 @@
+package state.state.impl;
+
+import state.context.GumballMachine;
+import state.state.State;
+
+public class SoldState implements State {
+    private final GumballMachine gumballMachine;
+
+    public SoldState(GumballMachine gumballMachine) {
+        this.gumballMachine = gumballMachine;
+    }
+
+    @Override
+    public void insertQuarter() {
+        System.out.println("동전을 넣음");
+    }
+
+    @Override
+    public void ejectQuarter() {
+        System.out.println("동전을 넣어 주세요");
+    }
+
+    @Override
+    public void turnCrank() {
+        System.out.println("동전을 넣어 주세요");
+    }
+
+    @Override
+    public void dispense() {
+        gumballMachine.releaseBall();
+        if (gumballMachine.getCount() > 0) {
+            gumballMachine.setState(gumballMachine.getNoQuarter());
+        } else {
+            System.out.println("gumballs가 부족합니다");
+            gumballMachine.setState(gumballMachine.getSoldOut());
+        }
+    }
+
+
+}
diff --git a/src/state/state/impl/WinnerState.java b/src/state/state/impl/WinnerState.java
new file mode 100644
index 0000000..7424975
--- /dev/null
+++ b/src/state/state/impl/WinnerState.java
@@ -0,0 +1,44 @@
+package state.state.impl;
+
+import state.context.GumballMachine;
+import state.state.State;
+
+public class WinnerState implements State {
+    private final GumballMachine gumballMachine;
+
+    public WinnerState(GumballMachine gumballMachine) {
+        this.gumballMachine = gumballMachine;
+    }
+
+    @Override
+    public void insertQuarter() {
+        System.out.println("동전을 넣음");
+    }
+
+    @Override
+    public void ejectQuarter() {
+        System.out.println("동전을 넣어 주세요");
+    }
+
+    @Override
+    public void turnCrank() {
+        System.out.println("동전을 넣어 주세요");
+    }
+
+    @Override
+    public void dispense() {
+        gumballMachine.releaseBall();
+        if (gumballMachine.getCount() == 0) {
+            gumballMachine.setState(gumballMachine.getSoldOut());
+        } else {
+            gumballMachine.releaseBall();
+            System.out.println("축하합니다! 알맹이를 하나 더 받을 수 있어요");
+            if (gumballMachine.getCount() > 0) {
+                gumballMachine.setState(gumballMachine.getNoQuarter());
+            } else {
+                System.out.println("더이상의 알맹이가 없습니다.");
+                gumballMachine.setState(gumballMachine.getSoldOut());
+            }
+        }
+    }
+}
