10-2 설계 패턴(생성 패턴)

윤효준·2025년 7월 23일

소프트웨어 공학

목록 보기
20/43

Abstract Factory (추상 팩토리) 패턴

🎯 의도 (Intent)

  • 관련성 있는 객체들의 집합(패밀리)을 생성하기 위한 인터페이스를 제공하며,
    구체적인 클래스는 지정하지 않고 객체들을 생성할 수 있도록 하는 패턴입니다.
  • 서로 관련된 객체들이 일관성 있게 사용되도록 보장하면서,
    클라이언트 코드가 구체 클래스에 의존하지 않도록(느슨한 결합) 합니다.
  • 팩토리 메서드(Factory Method)보다 더 큰 수준의 객체 생성(제품군 관리)을 지원합니다.

👉 즉, 제품군의 생성 로직을 캡슐화하여,
구체적인 클래스 없이도 서로 호환되는 객체들을 일관성 있게 생성할 수 있게 합니다.


🧩 구성 요소 (Participants)

  1. AbstractFactory (추상 팩토리 인터페이스)

    • 관련된 객체(제품군)를 생성하기 위한 추상 메서드 집합을 정의합니다.
    • 예: createButton(), createCheckbox().
  2. ConcreteFactory (구체 팩토리 클래스)

    • AbstractFactory를 구현하여,
      특정 제품군의 구체 객체들을 생성합니다.
    • 예: WindowsFactory, MacFactory.
  3. AbstractProduct (추상 제품 인터페이스)

    • 각 제품이 가져야 할 공통 인터페이스를 정의합니다.
    • 예: Button, Checkbox 인터페이스.
  4. ConcreteProduct (구체 제품 클래스)

    • AbstractProduct를 구현하여
      특정 팩토리에서 생성되는 실제 제품을 정의합니다.
    • 예: WindowsButton, MacButton.
  5. Client (클라이언트)

    • AbstractFactory 인터페이스를 사용하여 객체를 생성합니다.
    • 구체 클래스에 직접 의존하지 않고, 팩토리를 통해 객체 생성 및 사용을 수행합니다.

📌 작동 방식

  1. ClientAbstractFactory 인터페이스를 통해 객체 생성 요청을 합니다.
  2. ConcreteFactory가 요청받은 제품군의 구체 객체를 생성합니다.
  3. Client는 생성된 객체를 사용하지만, 구체 클래스는 알 필요가 없습니다.
  4. 제품군을 바꾸려면 팩토리 객체만 교체하면 됩니다.

Builder (빌더) 패턴

🎯 의도 (Intent)

  • 복잡한 객체의 생성 과정을 단계별로 캡슐화하여,
    동일한 생성 절차로도 서로 다른 표현(구성)의 객체를 만들 수 있도록 하는 패턴입니다.
  • 객체 생성 로직과 표현 방식을 분리하여,
    유연하고 가독성 높은 객체 생성을 지원합니다.
  • 특히 생성자의 인자가 많거나, 단계별 초기화가 필요한 경우 유용합니다.

👉 즉, 객체 생성 과정을 세분화하여
클라이언트가 객체를 단계적으로 조립할 수 있게 합니다.


🧩 구성 요소 (Participants)

  1. Builder (빌더 인터페이스)

    • 복잡한 객체를 생성하기 위한 단계별 메서드를 정의합니다.
    • 예: setPartA(), setPartB(), build().
  2. ConcreteBuilder (구체 빌더)

    • Builder 인터페이스를 구현하여
      각 단계별로 객체의 부분을 조립합니다.
    • 최종적으로 완성된 객체를 반환하는 메서드를 제공합니다.
  3. Product (제품 클래스)

    • 빌더가 생성하는 복잡한 객체입니다.
    • 여러 부품(Part)으로 구성되며, 단계적으로 조립됩니다.
  4. Director (감독자)

    • Builder를 사용하여 객체 생성의 순서(절차)를 정의합니다.
    • Builder의 메서드 호출 순서를 관리하지만, 구체적인 구현에는 관여하지 않습니다.
  5. Client (클라이언트)

    • DirectorConcreteBuilder를 사용하여 최종 객체를 생성합니다.
    • 어떤 Builder를 사용할지 선택함으로써 결과 객체를 다양하게 구성할 수 있습니다.

📌 작동 방식

  1. Client가 사용할 ConcreteBuilder를 선택하고 Director에 전달합니다.
  2. Director는 미리 정의된 절차에 따라 Builder의 메서드를 순차적으로 호출하여 객체를 조립합니다.
  3. ConcreteBuilder는 객체의 각 부분을 생성 및 조립하고, 완성된 Product를 반환합니다.
  4. 빌더만 교체하면, 동일한 절차로도 다른 표현의 객체를 만들 수 있습니다.

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

🎯 의도 (Intent)

  • 객체 생성을 서브클래스에 위임하여,
    클라이언트 코드가 구체 클래스(Concrete Class)에 의존하지 않도록 하는 패턴입니다.
  • 객체 생성 로직을 별도의 메서드(factoryMethod)로 분리하여,
    확장 시 새로운 제품을 쉽게 추가할 수 있습니다.
  • Abstract Factory와 달리, Factory Method는 하나의 제품(Product)을 생성하는 데 집중합니다.

👉 즉, 객체 생성을 캡슐화하여
상위 클래스는 생성의 인터페이스만 정의하고,
구체 클래스에서 실제 인스턴스를 결정하도록 합니다.


🧩 구성 요소 (Participants)

  1. Product (제품 인터페이스)

    • 생성될 객체들이 따라야 할 공통 인터페이스를 정의합니다.
    • 예: Button 인터페이스.
  2. ConcreteProduct (구체 제품 클래스)

    • Product 인터페이스를 구현하여 실제 생성될 객체를 정의합니다.
    • 예: WindowsButton, MacButton.
  3. Creator (창조자, 추상 클래스)

    • factoryMethod()라는 추상 메서드를 선언하여
      제품 객체 생성을 서브클래스에 위임합니다.
    • 또한, Product 객체를 사용하는 일반 메서드(템플릿 역할)를 포함할 수 있습니다.
  4. ConcreteCreator (구체 창조자)

    • CreatorfactoryMethod()를 구현하여
      어떤 ConcreteProduct를 생성할지 결정합니다.
  5. Client (클라이언트)

    • Creator를 통해 Product 객체를 사용하지만,
      구체적인 생성 로직은 알 필요가 없습니다.

📌 작동 방식

  1. ClientCreator의 메서드를 호출하여 제품을 생성합니다.
  2. Creator는 내부적으로 factoryMethod()를 호출하고,
    구체적인 제품 생성을 서브클래스(ConcreteCreator)에 위임합니다.
  3. 새로운 제품군이 필요하면 ConcreteProduct + ConcreteCreator만 추가하면 됩니다.

Prototype (프로토타입) 패턴

🎯 의도 (Intent)

  • 새로운 객체를 생성할 때,
    클래스를 명시적으로 지정하지 않고 기존 객체를 복제(Clone)하여 생성하는 패턴입니다.
  • 객체 생성 비용이 큰 경우(복잡한 초기화 과정, DB 연결, 네트워크 설정 등)
    기존 객체를 복사하여 새로운 인스턴스를 빠르게 생성할 수 있습니다.
  • 런타임에 동적으로 객체를 생성할 수 있으며,
    새로운 객체 유형을 추가할 때 클래스 계층 구조를 변경하지 않아도 됩니다.

👉 즉, 기존 객체를 복제(clone)하여 새로운 객체를 만드는 방식으로,
객체 생성의 유연성과 성능을 높이는 패턴입니다.


🧩 구성 요소 (Participants)

  1. Prototype (프로토타입 인터페이스)

    • 자신을 복제하는 메서드(예: clone())를 정의합니다.
    • 이 메서드를 통해 새로운 객체를 생성할 수 있습니다.
  2. ConcretePrototype (구체 프로토타입 클래스)

    • Prototype 인터페이스를 구현하고,
      clone() 메서드에서 자신의 복사본을 생성합니다.
    • 얕은 복사(Shallow Copy) 또는 깊은 복사(Deep Copy)를 구현할 수 있습니다.
  3. Client (클라이언트)

    • 새로운 객체를 만들 때 new 키워드 대신
      프로토타입 객체의 clone() 메서드를 호출하여 복제본을 생성합니다.
    • 복제할 객체의 구체적인 클래스는 몰라도 됩니다.

📌 작동 방식

  1. Client는 사용할 원형 객체(Prototype 인스턴스)를 미리 등록하거나 보관합니다.
  2. 새로운 객체가 필요할 때 clone()을 호출하여 원형 객체를 복제합니다.
  3. 복제된 객체는 원본과 같은 상태를 가지며, 필요 시 일부 속성을 수정할 수 있습니다.
  4. 새로운 타입의 객체를 추가할 때, Prototype 인터페이스를 구현한 클래스를 추가하기만 하면 됩니다.

Singleton (싱글톤) 패턴

🎯 의도 (Intent)

  • 애플리케이션에서 오직 하나의 인스턴스만 존재하도록 보장하고,
    그 인스턴스에 전역적으로 접근할 수 있는 방법을 제공하는 패턴입니다.
  • 시스템 전체에서 공유되는 리소스(예: 설정, 로그 기록, DB 연결 등)를 관리할 때 사용됩니다.
  • 인스턴스가 하나만 생성되도록 제어하므로 메모리 절약일관성 유지가 가능합니다.

👉 즉, 특정 클래스의 인스턴스가 단 하나만 존재하도록 보장하고,
어디서든 접근할 수 있는 전역적 접근점을 제공합니다.


🧩 구성 요소 (Participants)

  1. Singleton (싱글톤 클래스)

    • 자신의 유일한 인스턴스를 정적(Static) 필드로 보관합니다.
    • 외부에서 인스턴스를 생성하지 못하도록 생성자를 private으로 제한합니다.
    • 인스턴스에 접근하기 위해 *정적 메서드(getInstance())를 제공합니다.
  2. Client (클라이언트)

    • Singleton.getInstance()를 호출하여 유일한 인스턴스에 접근하고 사용합니다.
    • 여러 번 호출하더라도 항상 같은 인스턴스를 반환받습니다.

📌 작동 방식

  1. 최초 호출 시, getInstance()가 새로운 인스턴스를 생성하고 정적 필드에 저장합니다.
  2. 이후 호출 시, 기존에 생성된 인스턴스를 그대로 반환합니다.
  3. 인스턴스는 전역적으로 공유되며, 항상 동일한 객체를 참조합니다.

profile
작은 문제를 하나하나 해결하며, 누군가의 하루에 선물이 되는 코드를 작성해 갑니다.

0개의 댓글