본문 바로가기

Learning/.programming

[디자인 패턴] 1) 생성 패턴

728x90

1. 생성 패턴 (Creational Patterns)

생성 패턴은 객체 생성 과정을 캡슐화하거나 특정 로직에 따라 객체를 생성하는 패턴이다.
이를 통해 객체 생성 로직을 클라이언트 코드로부터 분리하고, 객체 생성을 더 유연하게 설계할 수 있다.


---

1.1 Singleton Pattern (싱글톤 패턴)

개념:
하나의 클래스에 대해 단 하나의 인스턴스만 생성하고, 이를 전역적으로 접근할 수 있게 하는 패턴.

구조 다이어그램:

+-------------+
              |  Singleton  |
              +-------------+
                    |
                    v
              +-------------+
              | getInstance |
              +-------------+

예제 코드:

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    public void display() {
        System.out.println("Singleton instance: " + this);
    }
}

public class Main {
    public static void main(String[] args) {
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        
        s1.display();
        s2.display();
    }
}

출력:

Singleton instance: Singleton@1a2b3c4
Singleton instance: Singleton@1a2b3c4

장단점:

장점: 메모리 절약, 인스턴스 제어

단점: 멀티스레딩 환경에서 동기화 문제 발생 가능



---

1.2 Factory Method Pattern (팩토리 메서드 패턴)

개념:
객체 생성을 서브클래스에 위임하여, 객체 생성을 캡슐화하는 패턴.

구조 다이어그램:

+-------------------+
        |   Product         |
        +-------------------+
               ▲
               |
   +--------------------+
   |  ConcreteProduct   |
   +--------------------+
               ▲
               |
   +--------------------+
   |   ProductFactory   |
   +--------------------+
           |
           v
   +--------------------+
   |   createProduct()  |
   +--------------------+

예제 코드:

interface Product {
    void use();
}

class ProductA implements Product {
    public void use() {
        System.out.println("Using Product A");
    }
}

class ProductB implements Product {
    public void use() {
        System.out.println("Using Product B");
    }
}

class ProductFactory {
    public static Product createProduct(String type) {
        switch (type) {
            case "A":
                return new ProductA();
            case "B":
                return new ProductB();
            default:
                throw new IllegalArgumentException("Unknown product type");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Product productA = ProductFactory.createProduct("A");
        Product productB = ProductFactory.createProduct("B");

        productA.use();
        productB.use();
    }
}

출력:

Using Product A
Using Product B

장단점:

장점: 객체 생성 로직을 분리하여 코드 재사용성 높임

단점: 서브클래스가 많아질 경우 관리가 어려워짐



---

1.3 Abstract Factory Pattern (추상 팩토리 패턴)

개념:
관련된 객체 군을 생성하는 인터페이스를 제공하고, 이를 구현한 팩토리 클래스에서 객체를 생성하는 패턴.

구조 다이어그램:

+---------------------+
      |   AbstractFactory   |
      +---------------------+
         /           \
+--------------+   +--------------+
| ConcreteA    |   | ConcreteB    |
+--------------+   +--------------+
      |                  |
+-------------+      +-------------+
| ProductA    |      | ProductB    |
+-------------+      +-------------+

예제 코드:

interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

interface Button {
    void click();
}

interface Checkbox {
    void check();
}

class MacFactory implements GUIFactory {
    public Button createButton() {
        return new MacButton();
    }

    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
}

class MacButton implements Button {
    public void click() {
        System.out.println("Mac Button Clicked");
    }
}

class MacCheckbox implements Checkbox {
    public void check() {
        System.out.println("Mac Checkbox Checked");
    }
}

public class Main {
    public static void main(String[] args) {
        GUIFactory macFactory = new MacFactory();
        Button button = macFactory.createButton();
        Checkbox checkbox = macFactory.createCheckbox();

        button.click();
        checkbox.check();
    }
}

출력:

Mac Button Clicked
Mac Checkbox Checked


---

1.4 Builder Pattern (빌더 패턴)

개념:
객체의 생성 과정을 단계별로 나누고, 각 단계에서 객체의 일부를 조립하여 최종 객체를 완성하는 패턴이다.

구조 다이어그램:

+-----------+
            |  Director |
            +-----------+
                  |
                  v
           +--------------+
           |   Builder    |
           +--------------+
                  |
       +----------+----------+
       |                     |
+-----------+          +-----------+
|  Product  |          |  Product  |
+-----------+          +-----------+

예제 코드:

class Product {
    private String partA;
    private String partB;

    public void setPartA(String partA) { this.partA = partA; }
    public void setPartB(String partB) { this.partB = partB; }

    public void show() {
        System.out.println("Product [PartA: " + partA + ", PartB: " + partB + "]");
    }
}

class ProductBuilder {
    private Product product = new Product();

    public ProductBuilder setPartA(String partA) {
        product.setPartA(partA);
        return this;
    }

    public Product build() {
        return product;
    }
}

public class Main {
    public static void main(String[] args) {
        ProductBuilder builder = new ProductBuilder();
        Product product = builder.setPartA("Engine").build();
        product.show();
    }
}

출력:

Product [PartA: Engine, PartB: null]


---

1.5 Prototype Pattern (프로토타입 패턴)

개념:
기존 객체를 복제하여 새로운 객체를 생성하는 패턴.

구조 다이어그램:

+-----------+
           | Prototype |
           +-----------+
                |
                v
       +-----------------+
       | ConcretePrototype |
       +-----------------+

예제 코드:

class Prototype implements Cloneable {
    private String name;

    public Prototype(String name) { this.name = name; }

    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    public void show() {
        System.out.println("Prototype: " + name);
    }
}

public class Main {
    public static void main(String[] args) {
        Prototype p1 = new Prototype("Original");
        Prototype p2 = p1.clone();

        p1.show();
        p2.show();
    }
}

출력:

Prototype: Original
Prototype: Original


300x250