Factory Method Pattern

Muzi·2023년 4월 20일
0

디자인 패턴

목록 보기
4/14

Intro

객체 생성을 직접하지 않고, 하위 클래스가 어떤 객체를 생성할지 결정하도록 위임하는 디자인 패턴

  • 팩토리는 말 그대로 객체를 찍어내는 공장을 의미
  • 객체의 생성을 직접하는게 아니라 팩토리 클래스에 위임해 객체를 생성하도록 하는 방식
  • 즉, 오버라이드된 메서드가 객체를 반환하는 패턴
  • 템플릿 메소드 패턴을 활용한 패턴

  • Creator - 제품 생성 인터페이스
  • ConcreteCreator - 실제로 제품을 생성하는 로직을 처리하는 서브 클래스
  • product - 제품 인터페이스

Why

설명을 잘해주셔서 참고하였습니다
설명을 잘해주셔서 참고하였습니다 2

아래 코드 TypeA, TypeB, TypeC는 Type 추상 클래스를 정의하여 캡슐화하고 ClassA에서 createType()에서 문자열 type에 따라 Type클래스 생성을 분기처리 한다

// Type.java
public abstract class Type {
}
// TypeA.java
public class TypeA extends Type {
    public TypeA() {
        System.out.println("Type A 생성");
    }
}
// TypeB.java
public class TypeB extends Type {
    public TypeB() {
        System.out.println("Type B 생성");
    }
}
// TypeC.java
public class TypeC extends Type {
    public TypeC() {
        System.out.println("Type C 생성");
    }
}
// ClassA.java
public class ClassA {
    public Type createType(String type) {
        Type returnType = null;

        switch (type) {
            case "A":
                returnType = new TypeA();
                break;
            case "B":
                returnType = new TypeB();
                break;
            case "C":
                returnType = new TypeC();
                break;
        }
        return returnType;
    }
}
// Client.java
public class Client {
    public static void main(String args[]) {
        ClassA classA = new ClassA();
        classA.createType("A");
        classA.createType("C");
    }
}

만약 객체를 생성하는 코드가 여러 클래스에서 사용하는 경우라면?

아래 처럼 중복코드가 클래스 개수만큼 생겨 높아진 결합도(의존도)는 유지보수를 어렵게 만든다


How

  1. 팩토리 클래스를 정의한다
  2. 객체 생성이 필요한 클래스에서 팩토리 객체를 생성, 분기에 따른 객체 생성 메소드 호출
// TypeFactory.java
public class TypeFactory {
    public Type createType(String type) {
        Type returnType = null;

        switch (type) {
            case "A":
                returnType = new TypeA();
                break;
            case "B":
                returnType = new TypeB();
                break;
            case "C":
                returnType = new TypeC();
                break;
        }
        return returnType;
    }
}
// ClassA.java
public class ClassA {
    public Type createType(String type) {
        TypeFactory factory = new TypeFactory();
        Type returnType = factory.createType(type);

        return returnType;
    }
}
  • 기존 classA에서 생성하던 일을 팩토리 클래스로 위임했다
  • 이제 type을 생성해야하는 클래스들은 팩토리 클래스를 사용하여 객체를 생성할 수 있다
  • 객체 생성 부분을 수정해야하는 경우 팩토리 클래스만 수정하면 되기에 유지보수 용이

장단점

장점

  1. 간결해진 코드
  2. 객체 생성 방법이 변경될 때, 하위 클래스의 변경을 최소화
  3. Product 와 Creator 간의 커플링(결합)이 느슨해짐
  4. 서브 클래스에 생성을 위임하므로 의존성을 제거한다

단점

  1. 제품 클래스가 바뀔때마다 새로운 서브 클래스를(제품을 생성하는) 생성해야한다
  2. 클라이언트가 creator 클래스를 반드시 상속해 Product를 생성해야 한다
  3. 간단한 기능을 사용할 때보다 많은 클래스를 정의해야 하기 때문에 클래스가 많아짐

Tip

Java 8 인터페이스 default method

  • 인터페이스의 default method를 사용하면 상속받는 서브 클래스의 중복 코드를 줄일 수 있음

Java 9 인터페이스 private method

  • 기능 구현 뿐 아니라 인터페이스 내부 로직을 private 메소드로 구현해 가독성 향상 가능


Reference

https://dev-youngjun.tistory.com/195
https://bcp0109.tistory.com/367
https://velog.io/@newtownboy/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%ED%8C%A9%ED%86%A0%EB%A6%AC%EB%A9%94%EC%86%8C%EB%93%9C%ED%8C%A8%ED%84%B4Factory-Method-Pattern
https://www.google.com/search?q=%ED%85%9C%ED%94%8C%EB%A6%BF+%EB%A9%94%EC%86%8C%EB%93%9C+%ED%8C%A9%ED%86%A0%EB%A6%AC+%EB%A9%94%EC%86%8C%EB%93%9C&oq=%ED%85%9C%ED%94%8C%EB%A6%BF+%EB%A9%94%EC%86%8C%EB%93%9C+%ED%8C%A9%ED%86%A0%EB%A6%AC+%EB%A9%94%EC%86%8C%EB%93%9C&aqs=chrome..69i57.8053j0j7&sourceid=chrome&ie=UTF-8
https://velog.io/@borab/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-2-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A9%94%EC%84%9C%EB%93%9C-%ED%8C%A8%ED%84%B4-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C-%ED%8C%A8%ED%84%B4-%EC%B6%94%EC%83%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%ED%8C%A8%ED%84%B4#%EF%B8%8F-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C-%ED%8C%A8%ED%84%B4-%EC%83%9D%EC%84%B1-%ED%8C%A8%ED%84%B4%EF%B8%8F

profile
좋아하는걸 열심히

0개의 댓글