[디자인패턴] 생성 패턴 (Creational Patterns)

엔스마트·2024년 6월 23일

디자인 패턴

목록 보기
2/4

생성 패턴(Creational Patterns)은 객체 생성의 메커니즘을 다루는 디자인 패턴으로, 객체 생성 과정을 캡슐화하고 클라이언트 코드와의 결합도를 낮춰 유연성과 재사용성을 높입니다. 아래에서는 대표적인 생성 패턴들에 대해 상세히 분석하겠습니다.

1. 싱글톤 패턴 (Singleton Pattern)

  • 목적: 클래스의 인스턴스가 오직 하나만 생성되도록 보장하며, 이 인스턴스에 대한 전역 접근을 제공합니다.
  • 구현:
    • 클래스 내에 인스턴스를 정적 변수로 선언
    • 인스턴스를 반환하는 정적 메서드 제공
    • 생성자를 private으로 선언하여 외부에서 직접 인스턴스 생성 불가
public class Singleton {
    private static Singleton instance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 활용 예시: 로깅, 설정 클래스, 데이터베이스 연결등

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

  • 목적: 객체 생성 코드를 서브클래스에 위임하여 객체 생성 방식을 정의합니다.
  • 구현:
    • 부모 클래스에 객체 생성을 위한 추상 메서드 선언
    • 서브클래스에서 구체적인 객체 생성 메서드 구현
abstract class Product {
    public abstract void use();
}

class ConcreteProductA extends Product {
    public void use() {
        System.out.println("Using ConcreteProductA");
    }
}

class ConcreteProductB extends Product {
    public void use() {
        System.out.println("Using ConcreteProductB");
    }
}

abstract class Creator {
    public abstract Product factoryMethod();
}

class ConcreteCreatorA extends Creator {
    public Product factoryMethod() {
        return new ConcreteProductA();
    }
}

class ConcreteCreatorB extends Creator {
    public Product factoryMethod() {
        return new ConcreteProductB();
    }
}
  • 활용 예시: 다양한 제품군 객체 생성등

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

  • 목적: 관련 객체들을 생성하는 인터페이스를 제공합니다.
  • 구현:
    • 여러 팩토리 메서드를 포함하는 인터페이스 혹은 추상 클래스를 정의
    • 각 팩토리가 관련된 제품군을 생성
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

class WinFactory implements GUIFactory {
    public Button createButton() {
        return new WinButton();
    }
    
    public Checkbox createCheckbox() {
        return new WinCheckbox();
    }
}

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

interface Button {
    void paint();
}

interface Checkbox {
    void paint();
}

class WinButton implements Button {
    public void paint() {
        System.out.println("Rendering a button in Windows style.");
    }
}

class MacButton implements Button {
    public void paint() {
        System.out.println("Rendering a button in Mac style.");
    }
}

class WinCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Rendering a checkbox in Windows style.");
    }
}

class MacCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Rendering a checkbox in Mac style.");
    }
}
  • 활용 예시: 여러 제품군을 지원하는 UI 라이브러리등

4. 빌더 패턴 (Builder Pattern)

  • 목적: 복잡한 객체를 단계별로 생성할 수 있도록 합니다.
  • 구현:
    • 빌더 클래스에서 객체의 각 부분을 정의
    • 최종적으로 빌더를 통해 객체 생성
class Product {
    private String partA;
    private String partB;
    
    public Product(String partA, String partB) {
    	this.partA = partA;
    	this.partB = partB;
    }
}

class ProductBuilder {
    private String partA;
    private String partB;

    public ProductBuilder() { }
    
    public ProductBuilder partA(String partA) {
    	this.partA = partA;
        return this;
    }
    
    public ProductBuilder partB(String partB) {
    	this.partB = partB;
        return this;
    }
    
    public Product build() { 
        return new Product(this.partA, this.partB);
    }
}
  • 활용 예시: 복잡한 객체의 단계별 구성, 예를 들어 자동차 제조등

5. 프로토타입 패턴 (Prototype Pattern)

  • 목적: 기존 객체를 복제하여 새로운 객체를 생성합니다.
  • 구현:
    • 복제할 수 있는 인터페이스 구현
    • 복제 메서드를 통해 새로운 인스턴스 생성
abstract class Prototype implements Cloneable {
    public Prototype clone() throws CloneNotSupportedException {
        return (Prototype) super.clone();
    }
}

class ConcretePrototype extends Prototype {
    private String field;
    
    public ConcretePrototype(String field) {
        this.field = field;
    }
    
    public String getField() { return field; }
}
  • 활용 예시: 객체 생성 비용이 클 때, 객체 복제를 통한 성능 최적화등

생성 패턴의 장점과 단점

장점

  • 캡슐화: 객체 생성 로직을 캡슐화하여 코드의 가독성과 유지 보수성을 높입니다.
  • 유연성: 객체 생성 방식을 변경해도 클라이언트 코드에 영향을 주지 않도록 합니다.
  • 재사용성: 생성 로직을 재사용 가능하게 만들어 코드 중복을 줄입니다.

단점

  • 복잡성 증가: 객체 생성에 관련된 추가적인 클래스나 인터페이스가 필요하여 코드의 복잡성이 증가할 수 있습니다.
  • 초기 설정 부담: 패턴을 잘못 적용할 경우 초기 설정에 부담이 될 수 있습니다.

생성 패턴은 객체 생성의 유연성과 재사용성을 높이기 위해 사용되며, 다양한 상황에서 객체 생성의 복잡성을 효과적으로 관리할 수 있는 방법을 제공합니다. 각 패턴을 상황에 맞게 적용하는 것이 중요합니다.

profile
클라우드 전환, MSA 서비스, DevOps 환경 구축과 기술지원 그리고 엔터프라이즈 시스템을 구축하는 최고 실력과 경험을 가진 Architect Group 입니다.

0개의 댓글