EEALL@ONCE

🔦팩토리 패턴(Factory Pattern)이 뭔데? 본문

분류없음지식🔦

🔦팩토리 패턴(Factory Pattern)이 뭔데?

올엣원스 2023. 12. 6. 08:55
728x90

팩토리 패턴(Factory Pattern)은 객체 생성을 처리하는 디자인 패턴 중 하나로, 객체를 생성하는 코드를 클라이언트로부터 분리시키는 목적을 갖고 있습니다. 주로 인터페이스를 통해 객체를 생성하고, 실제 생성할 클래스의 결정은 팩토리 클래스가 담당합니다.

간단한 예시로 설명하겠습니다. 가령, 데이터베이스 연결 객체를 생성하는 상황을 가정해봅시다. 팩토리 패턴을 사용하면 클라이언트는 어떤 데이터베이스에 연결할지에 대한 구체적인 클래스를 알 필요 없이, 단지 팩토리 인터페이스를 통해 객체를 생성할 수 있습니다.

이를 Java 코드로 표현하면 다음과 같습니다:

// 인터페이스
interface DatabaseConnection {
    void connect();
}

// 구체적인 클래스들
class MySqlConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("MySQL에 연결됨");
    }
}

class OracleConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("Oracle에 연결됨");
    }
}

// 팩토리 인터페이스
interface ConnectionFactory {
    DatabaseConnection createConnection();
}

// 구체적인 팩토리 클래스들
class MySqlConnectionFactory implements ConnectionFactory {
    @Override
    public DatabaseConnection createConnection() {
        return new MySqlConnection();
    }
}

class OracleConnectionFactory implements ConnectionFactory {
    @Override
    public DatabaseConnection createConnection() {
        return new OracleConnection();
    }
}



이렇게 하면 클라이언트는 단순히 `ConnectionFactory` 인터페이스를 통해 데이터베이스 연결 객체를 생성하고, 어떤 구체적인 데이터베이스에 연결되는지는 알 필요가 없어집니다. 이는 코드의 유연성과 확장성을 높여주는 장점이 있습니다.


팩토리 패턴(Factory Pattern)은 객체 생성을 캡슐화하고 객체의 구체적인 클래스와 클라이언트 코드를 분리하기 위한 디자인 패턴 중 하나입니다. 이 패턴은 객체를 생성하는 코드를 클라이언트 코드에서 분리함으로써 유연성을 높이고, 객체의 생성 방법을 추상화하여 클라이언트가 생성 로직에 대해 알 필요가 없도록 합니다.

팩토리 패턴은 주로 다음 두 가지 방법으로 구현됩니다:

  1. 간단한 팩토리 메서드 (Simple Factory Method): 객체 생성을 위한 단일 메서드를 가진 팩토리 클래스를 만드는 방식입니다. 클라이언트는 이 팩토리 메서드를 호출하여 객체를 얻습니다.
  2. 추상 팩토리 메서드 (Abstract Factory Method): 여러 관련된 객체의 생성을 담당하는 인터페이스를 제공하고, 각 구체적인 팩토리 클래스가 이 인터페이스를 구현하여 객체를 생성하는 방식입니다. 이를 통해 클라이언트는 팩토리의 인터페이스를 통해 객체를 생성하게 됩니다.

간단한 예시를 통해 이해해보겠습니다. 가령, 동물을 나타내는 객체를 생성하는 팩토리 패턴을 고려해보겠습니다.

// 동물 인터페이스
public interface Animal {
    void makeSound();
}

// 강아지 클래스
public class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("멍멍!");
    }
}

// 고양이 클래스
public class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("야옹!");
    }
}

// 동물 팩토리 인터페이스
public interface AnimalFactory {
    Animal createAnimal();
}

// 강아지 팩토리
public class DogFactory implements AnimalFactory {
    @Override
    public Animal createAnimal() {
        return new Dog();
    }
}

// 고양이 팩토리
public class CatFactory implements AnimalFactory {
    @Override
    public Animal createAnimal() {
        return new Cat();
    }
}

이렇게 하면 클라이언트는 어떤 동물을 생성할지에 대한 결정을 팩토리에 위임할 수 있습니다. 팩토리 패턴을 사용하면 새로운 동물이 추가되거나 기존 동물의 구현이 변경되어도 클라이언트 코드에 영향을 미치지 않으면서, 팩토리에 필요한 수정만으로 새로운 동물을 추가할 수 있습니다.

 

팩토리 패턴을 사용하는 클라이언트 코드는 객체를 직접 생성하지 않고, 대신 팩토리를 통해 필요한 객체를 생성합니다. 이로써 객체 생성 로직과 클라이언트 코드가 분리되어 유연성이 향상됩니다.

클라이언트 코드는 팩토리의 인터페이스나 메서드를 호출하여 객체를 얻습니다. 이때 클라이언트는 실제 생성되는 구체적인 객체에 대한 세부 정보를 몰라도 됩니다. 아래는 팩토리 패턴을 사용하는 클라이언트 코드의 예시입니다:

 


🧐그럼 팩토리 패턴 안쓰면 뭐가 불편한거야?

이 경우에는 클라이언트 코드가 직접 Dog와 Cat 클래스를 생성하고 있습니다. 이로 인해 클라이언트 코드는 특정 동물에 강하게 결합되어 있어, 만약 다른 동물을 사용하려면 클라이언트 코드를 직접 수정해야 합니다. 또한, 객체 생성 로직이 클라이언트 코드에 노출되어 있기 때문에 유지보수가 어려워질 수 있습니다.

반면에 팩토리 패턴을 사용하면 객체 생성 로직이 팩토리에 캡슐화되어 있어, 클라이언트 코드는 어떤 객체가 생성되는지 알 필요가 없으며, 새로운 객체를 추가하거나 변경해도 클라이언트 코드를 수정하지 않아도 됩니다. 🤥팩토리 패턴은 객체 생성 로직의 변경에 유연하게 대처할 수 있도록 도와주는 디자인 패턴 중 하나입니다.


🧐 근데 사실상 dogfactory를 골랐다는거 자체가 dog를 선택했다는거잖아 그게 무슨 은닉이야 ? 
 
 
 

네, 맞습니다. 팩토리 패턴을 사용하더라도 클라이언트는 어떤 구체적인 팩토리를 선택하느냐에 따라서 원하는 객체가 생성되기 때문에 완전한 은닉은 아닙니다. 클라이언트가 어떤 종류의 객체를 생성할지 선택하는 책임은 클라이언트에게 남아 있습니다.

간단한 예제에서는 팩토리를 선택하는 과정이 명시적으로 이루어져서 은닉이 미미한 것처럼 보일 수 있습니다. 그러나 대규모 프로젝트에서는 팩토리 패턴이 객체 생성을 추상화하여, 객체 생성 방법이나 클래스 구조의 변경에 유연하게 대처할 수 있도록 합니다.

팩토리 패턴의 핵심은 객체 생성 코드를 클라이언트로부터 분리하여 캡슐화하고, 객체의 구체적인 클래스에 대한 의존성을 낮추는 것입니다. 이로써 클라이언트 코드는 객체 생성의 세부적인 내용에 대해 모르거나 신경 쓰지 않아도 되며, 팩토리를 통해 어떤 객체를 생성할지 결정할 수 있습니다.

 

🧐 새로운 객체를 추가하거나 변경해도 클라이언트 코드를 수정하지 않아도 됩니다. <- 이것도 팩토리를 바꿔줘야하는 수정이 필요한거 아냐?

 

올바른 지적입니다. 팩토리를 변경하거나 새로운 객체를 추가하는 경우에는 클라이언트 코드가 수정되어야 합니다. 그러나 팩토리 패턴이 제공하는 이점은 이러한 변경이 객체 생성 코드가 사용되는 클라이언트 코드에 영향을 미치지 않는다는 것입니다.

클라이언트 코드가 특정 객체를 직접 생성하는 것이 아니라 팩토리를 통해 생성하면, 새로운 객체를 추가하거나 기존 객체를 변경할 때 클라이언트 코드를 최소한으로 수정할 수 있습니다. 팩토리만 적절히 수정되면 클라이언트 코드는 변경에 영향을 받지 않습니다.

이러한 유연성은 특히 프로젝트가 커지고 복잡해질수록 중요해지며, 객체 생성 부분의 변경이 다른 부분에 미치는 영향을 최소화합니다. 팩토리 패턴은 이러한 객체 생성 로직을 캡슐화하여 시스템의 유지보수성과 확장성을 향상시키는 데 기여합니다.

 



내가 이해한 팩토리 패턴은... ? 

로직을 숨기는 걸 너무 좋아하고, 외부로 코드를 노출되는걸 극도로 꺼리는 

그런.. 보안적인 부분과 .. 뭐  내부 로직이 복잡할수록 그걸 가져다 와서 쓰는 쪽은 덜 수정할 수 있게 하는 

뭐 그런것 같은데 의존성 주입과도 굉장히 밀접한 

그런 개념이다. 

 

뭔가 레시피 노출하기 싫거나 

내부 사정을 모르고 싶을 때 사용하는게 내가 이해한 팩토리 패턴이다...

사실 심플한 예제로는 딱히 왜쓰는지 잘 와닿지 않지만.. 

뭔가 대형 프로젝트에서는 그럴 듯도 싶다. 

 

728x90