비트를 쪼개는 개발자

allen321@naver.com

C#

C# [디자인 패턴] - 팩토리 패턴(Factory Pattern)

MozarTnT 2024. 10. 24. 17:31
728x90
반응형

 

 

 

팩토리 패턴(Factory Pattern)이란?

 

  • 팩토리 패턴(Factory Pattern)은 객체 생성 로직을 클라이언트 코드와 분리하여 객체 생성을 관리하는 디자인 패턴이다.
  • 객체 생성 로직을 별도의 클래스나 메서드로 분리하여, 클라이언트 코드가 직접 객체를 생성하지 않고 팩토리를 통해 객체를 생성하도록 한다.
  • 팩토리 메서드만 수정하면 객체 생성 방식을 변경할 수 있으므로, 코드 수정이 유연해진다.
  • 팩토리 패턴은 크게 두가지로 분류된다. ("팩토리 메서드 패턴"과 "추상 팩토리 패턴")

 

 

 

팩토리 매서드 패턴

 

 

 

 

 

  • 팩토리 매서드 패턴은 객체를 생성하는 메서드를 캡슐화하여 서브클래스에서 구체적인 생성 방식을 정의하게 한다.
  • 객체 생성을 일종의 공장(팩토리) 클래스로 생성을 전담시키고 나머지 자세한 부분은 서브 클래스에서 전담한다.
  • 클라이언트가 구체적인 객체 타입을 알지 않고도 객체를 생성할 수 있어, 코드의 의존성이 낮아진다.

 

1. Creator : 팩토리 클래스의 최상위 클래스 - 팩토리 메서드를 추상화해서 서브 클래스가 이를 이용해 구현하도록 한다.

  • factoryMethod() : 서브 클래스 에서 재정의하여 객체를 생성할 추상 메서드다.

2. ConcreteCreator : 각각의 서브 공장 클래스로 호출에 맞는 Product를 반환 처리 하도록 추상 메서드를 재정의하는 서브클래스다. 

 

3. Product : 팩토리 메서드가 생성하는 제품이고 반환할 객체의 타입을 정의해야 한다.

  • ConcreteProduct : 이에 맞게 실제로 생성된 객체들을 의미한다.

 

 

팩토리 메소드 패턴을 구현하는건 하나의 공장을 만드는 것과 비슷하다.

 

캡슐화와 추상화를 통해 객체가 생성되기 때문에 객체의 구체적인 타입을 감출 수 있어 생성자와 구현 객체 간 강한 결합을 피하게 해준다.

 

 

 

 

추상 팩토리 패턴

 

 

 

  • 추상 팩토리 패턴은 연관성이 있는 객체들을 묶어 추상화 하고 특정한 상황이 주어지면 집합으로 묶은 객체들을 구현하는 패턴이다.
  • 주로 인터페이스를 사용하여 구현하고 객체들의 구체적인 클래스를 지정하지 않고도 해당 제품군의 집합을 생성할 수 있다.
  • 추상 팩토리 패턴 역시 객체 생성 과정에서 캡슐화를 통해 클라이언트와 구현부를 분리하였기 떄문에 느슨한 결합 구조를 유지할 수 있다.

 

1. AbstractFactory : 제품군을 생성할 최상위 메서드 - 서로 다른 제품들을 생성하는 메서드들을 추상화 시켜준다.

 

2. ConcreteFactory : 각 서브 공장 클래스들로 객체의 생성을 구체화하는 클래스다. 여기서 타입에 맞는 제품 객체를 반환한다.

 

3. AbstractProduct : 각 타입의 제품을 추상화하고 제품들이 따라야 할 인터페이스다.

 

4. ConcreteProduct : 각 타입의 제품들을 구현한 것으로 제품들의 구현은 ConcreteFactory를 통해 생성된다.

 

5. Client : 제품 생성을 요청한 클라이언트로 구체적인 과정은 모르지만 원하는 타입의 제품을 반환받는다.

 

 

 

팩토리 메서드 패턴과 추상 팩토리 패턴은 객체 생성 과정을 추상화하고 캡슐화 한다는 점은 동일하다.

 

하지만 이를 구현하는 과정에서 팩토리 메서드 패턴은 객체 생성 이후에 해야 할 일들을 지정해 주고 정의하는 것을 최우선적으로 전담하지만, 추상 팩토리 패턴은 생성 할 객체들의 집합 군의 공통점을 찾는것에 우선점을 둔다.

 

 

 

팩토리 메서드와 추상 팩토리 패턴의 차이점

 

 

비교 사항 팩토리 메서드 패턴 추상 팩토리 패턴
목적 각 객체의 생성 방식은 서브 클래스에서 정의함 비슷한 객체들의 집합을 생성하는 인터페이스를 제공함
구조 하나의 객체 생성 메서드를 서브 클래스에서 구체화 하고 구현한다 여러 객체를 생성하는 메서드를 팩토리 인터페이스가 포함한다
유연성 객체의 구체적 로직을 서브 클래스에 위임 특정 제품군을 교체하기 용이함
사용 상황 객체 생성 방식이 자주 변경되거나 객체 생성 로직 자체를 캡슐화 하고 싶은 경우 특정 제품군을 생성하지만 교체가 빈번한 경우
확장성 새로운 객체의 유형을 추가하기 쉬움 새로운 제품군을 추가 할 시 추상 팩토리와 구체 팩토리들을 모두 수정해야 함
단순성 상대적으로 단순함 상대적으로 복잡함

 

 

 

사용 예시 코드

// 초콜릿 인터페이스: Product 역할
// 다양한 초콜릿 클래스들이 구현해야 하는 인터페이스.
public interface IChocolate
{
    void Make();
}

// 밀크 초콜릿 클래스: ConcreteProduct 역할
// 실제로 밀크 초콜릿을 생성하고, 동작을 정의
public class MilkChocolate : IChocolate
{
    public void Make()
    {
        Console.WriteLine("밀크 초콜릿 생성.");
    }
}

// 다크 초콜릿 클래스: ConcreteProduct 역할
// 실제로 다크 초콜릿을 생성하고, 동작을 정의
public class DarkChocolate : IChocolate
{
    public void Make()
    {
        Console.WriteLine("다크 초콜릿 생성.");
    }
}

// 화이트 초콜릿 클래스: ConcreteProduct 역할
// 실제로 화이트 초콜릿을 생성하고, 동작을 정의
public class WhiteChocolate : IChocolate
{
    public void Make()
    {
        Console.WriteLine("화이트 초콜릿 생성.");
    }
}

// 초콜릿 팩토리 추상 클래스: Creator 역할
// 팩토리 메서드를 정의하여 구체적인 초콜릿 객체 생성의 인터페이스를 제공
public abstract class ChocolateFactory
{
    // 팩토리 메서드: ConcreteCreator에서 구체적으로 구현할 메서드.
    // 이 메서드를 통해 초콜릿 객체를 생성
    public abstract IChocolate CreateChocolate();

    // 공통 작업 메서드: 모든 초콜릿 제조에 공통적으로 필요한 로직을 정의
    public void PrepareChocolate()
    {
        var chocolate = CreateChocolate();
        chocolate.Make();
    }
}

// 밀크 초콜릿 팩토리: ConcreteCreator 역할
// 밀크 초콜릿을 생성하는 팩토리 클래스.
public class MilkChocolateFactory : ChocolateFactory
{
    // 밀크 초콜릿 객체를 생성하여 반환
    public override IChocolate CreateChocolate()
    {
        return new MilkChocolate();
    }
}

// 다크 초콜릿 팩토리: ConcreteCreator 역할
// 다크 초콜릿을 생성하는 팩토리 클래스.
public class DarkChocolateFactory : ChocolateFactory
{
    // 다크 초콜릿 객체를 생성하여 반환
    public override IChocolate CreateChocolate()
    {
        return new DarkChocolate();
    }
}

// 화이트 초콜릿 팩토리: ConcreteCreator 역할
// 화이트 초콜릿을 생성하는 팩토리 클래스.
public class WhiteChocolateFactory : ChocolateFactory
{
    // 화이트 초콜릿 객체를 생성하여 반환
    public override IChocolate CreateChocolate()
    {
        return new WhiteChocolate();
    }
}

 

 

 

  • IChocolate (Product): 다양한 초콜릿 객체들이 구현할 인터페이스를 정의한다.
  • MilkChocolate, DarkChocolate, WhiteChocolate (ConcreteProduct): 실제로 생성될 초콜릿 클래스들로, IChocolate 인터페이스를 받아 구현한다.
  • ChocolateFactory (Creator): 팩토리 메서드를 정의하여 구체적인 초콜릿 객체를 생성하는 인터페이스를 제공한다.
  • MilkChocolateFactory, DarkChocolateFactory, WhiteChocolateFactory (ConcreteCreator): ChocolateFactory를 상속받아 각각의 초콜릿을 생성하는 클래스로, 구체적인 팩토리 메서드를 구현한다.

이를 Main문으로 호출 후 실행하면 다음과 같다.

 

 

static void Main(string[] args)
{
    ChocolateFactory milkFactory = new MilkChocolateFactory();
    milkFactory.PrepareChocolate();

    ChocolateFactory darkFactory = new DarkChocolateFactory();
    darkFactory.PrepareChocolate();

    ChocolateFactory whiteFactory = new WhiteChocolateFactory();
    whiteFactory.PrepareChocolate();
}

 

 

 

 

 

 

 

 

 

 

사진 출처 : 

https://ko.wikipedia.org/wiki/%ED%8C%A9%ED%86%A0%EB%A6%AC_%EB%A9%94%EC%84%9C%EB%93%9C_%ED%8C%A8%ED%84%B4

https://www.linkedin.com/pulse/factory-design-pattern-can-help-deepak-atariya/

728x90
반응형