반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • 일상, 일기 (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • item9
  • 싱글톤
  • 알고리즘
  • item7
  • 자바스크립트
  • 러스트
  • 빈 검증
  • 도커공식문서
  • next js app
  • MSSQL
  • Javadoc 자바독 자바주석 주석 Comment
  • Java
  • 자바스크립트 면접
  • 자바 검증
  • 참조 해제
  • 슬로우 쿼리
  • 자료구조
  • 이펙티브자바
  • rust
  • Pre-rendering
  • item8
  • 외래키 제약조건
  • 작업기억공간
  • 추상 팩터리 패턴
  • 싱글톤 패턴
  • 메이븐 라이프사이클
  • 팩터리 메서드 패턴
  • serverless computing
  • try-with-resources
  • 메이븐 골
  • 프로그래머의 뇌
  • 객체복사
  • 느린 쿼리
  • 자바 디자인패턴
  • 메이븐 페이즈
  • 서버리스 컴퓨팅
  • Next.js
  • 자바스크립트 인터뷰
  • pnpm
  • 디자인패턴
  • 스프링 검증
  • 이펙티브 자바 item9
  • bean Validation
  • 이펙티브 자바
  • NEXT JS
  • 플라이웨이트패턴
  • 싱글턴
  • 자바
  • 토비의 스프링
  • prerendering

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

추상 팩토리 패턴 (Abstract Factory Pattern) 이란?
Java/자바 디자인 패턴

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

2023. 1. 24. 02:59

추상 팩토리 패턴이란?

  • 서로 관련된 여러 객체를 만들어주는 인터페이스를 제공하고 이를 구현하는 패턴
  • 관련이 깊은 여러 종류의 객체를 일관된 방식으로 생성하는 경우에 유용하다.
  • 팩토리 메서드 패턴 과 굉장히 비슷하다.
  • 팩토리 메서드 패턴 은 하나의 객체 생성을 어떻게 할까에 집중하는 반면, 추상 팩토리 패턴은 관련 있는 여러 객체를 묶어 여러 구체적 클래스에 의존하지 않는 것에 집중한다.

다이어그램으로 살펴보기

  • AbstractFactory 는 CreateProductA() 와 CreateProductB() 라는 추상 메서드를 제공한다.
    • ProductA 와 ProductB 를 생성한다.
    • 구체적인 객체 생성 방법의 구현은 하위 클래스에게 맡긴다.
  • ConcreteFactory1 과 ConcreteFactory2 는 ProductA 와 ProductB 객체를 생성할 구체적인 생성 코드를 가지고 있다.

현실 세계와의 비유: 자동차 공장

  • 자동차 라는 완제품에 엔진 과 타이어 는 반드시 필요하다.
    • 두 객체는 서로 관련이 깊다고 볼 수 있다.
    • 두 부품이 모두 같은 회사의 공장에서 나온다.
    • 두 부품외 다른 종류의 부품은 모든 차가 같은 것을 쓴다고 가정하자.

디자인 패턴이 적용되지 않은 코드 살펴보기

public class SonataPartsFactory {
    public CVVLEngine createCVVLEngine() {
        return new CVVLEngine();
    }

    public HankookTire createHankookTire() {
        return new HankookTire();
    }
}

public class K9PartsFactory {
    public V8Engine createV8Engine() {
        return new V8Engine();
    }

    public MichelinTire createMichelinTire() {
        return new MichelinTire();
    }
}

@AllArgsConstructor
@ToString
public class Car {
    private final Engine engine;
    private final Tire tire;
}

public class Client {
    public static void main(String[] args) {
        K9PartsFactory k9PartsFactory = new K9PartsFactory();
        SonataPartsFactory sonataPartsFactory = new SonataPartsFactory();

        // create k9 car parts.
        V8Engine v8Engine = k9PartsFactory.createV8Engine();
        MichelinTire michelinTire = k9PartsFactory.createMichelinTire();
        System.out.println("k9 엔진 : " + v8Engine);
        System.out.println("k9 타이어 : " + michelinTire);
        System.out.println("k9 생산: " + new Car(v8Engine, michelinTire));

        // create sonata car parts.
        CVVLEngine cvvlEngine = sonataPartsFactory.createCVVLEngine();
        HankookTire hankookTire = sonataPartsFactory.createHankookTire();
        System.out.println("쏘나타 엔진 생산: " + cvvlEngine);
        System.out.println("쏘나타 타이어 생산: " + hankookTire);
        System.out.println("쏘나타 생산: " + new Car(cvvlEngine, hankookTire));
    }
}
  • Sonata 와 K9 부품 공장의 구현 예제이다.
  • 자동차에 필요한 부품인 엔진과 타이어를 모두 구체적으로 생성하고 있다.
  • 반환 타입과 메서드명이 모두 구체적이라서 생성 객체가 바뀌어야 하면 모든 코드도 같이 바뀌어야 한다.
    • ...PartsFactory 코드와 이를 가져다 쓰는 Client 코드가 같이 바뀌어야 한다.

디자인패턴 적용하기

  • 추상 팩토리 패턴을 적용해보자.

추상 팩토리 만들기

public interface Engine {
}

public interface Tire {
}

public interface CarPartsFactory {
    Engine createEngine();
    Tire createTire();
}
  • Sonata 와 K5 를 Car 라는 단어로 추상화하여 추상 팩토리를 만들었다.
    • CVVLEngine 과 HankookTire 등도 Engine 과 Tire 로 추상화하였다.
  • 추상 팩토리는 연관된 객체를 생성하는 추상 메서드를 가지고 있는 인터페이스이다.
  • 자동차를 만드는데 필요한 부품을 모아놨으므로 코드의 응집도에도 좋다.

추상 팩토리 클라이언트 클래스 만들기

public class CarFactory {
    private final CarPartsFactory carPartsFactory;

    public CarFactory(CarPartsFactory carPartsFactory) {
        this.carPartsFactory = carPartsFactory;
    }

    public Car createCar() {
        return new Car(
                carPartsFactory.createEngine(),
                carPartsFactory.createTire()
        );
    }
}
  • CarPartsFactory 를 주입받아 사용하는 클래스이다.
  • 이 클래스는 어떤 엔진과 어떤 타이어를 가진 자동차를 만들더라도 절대 변할 일이 없다.

디자인 패턴이 적용되지 않았던 코드 개선하기

public class K9PartsFactory implements CarPartsFactory{
    @Override
    public Engine createEngine() {
        return new V8Engine();
    }

    @Override
    public Tire createTire() {
        return new MichelinTire();
    }
}

public class SonataPartsFactory implements CarPartsFactory {
    @Override
    public Engine createEngine() {
        return new CVVLEngine();
    }

    @Override
    public Tire createTire() {
        return new HankookTire();
    }
}
  • CarPartsFactory 인터페이스를 상속하도록 바뀌었다.
  • 추상 팩토리의 구현체이다.

클라이언트 코드 개선하기

public class Client {
    public static void main(String[] args) {
        CarFactory k9Factory = new CarFactory(new K9PartsFactory());
        CarFactory sonataFactory = new CarFactory(new SonataPartsFactory());

        System.out.println("K9 생산 : " + k9Factory.createCar());
        System.out.println("Sonata 생산 : " + sonataFactory.createCar());
    }
}
  • CarFactory 를 생성하고 부품 공장만 주입해주면, 자동차 공장을 만들 수 있게 되었다.
  • 앞으로 어떠한 새로운 차가 나오더라도 CarFactory 클래스는 변할 일이 없다.
  • 새로운 차가 나온다면, 어떤 엔진을 사용하고 어떤 타이어를 사용하는지를 명시하는 CarPartsFactory 를 상속한 구현 클래스를 만들어주기만 하면 된다.
    • CarFactory 나 CarPartsFactory 등을 수정할 필요가 없는 점은 변경에 닫혀있다고 볼 수 있다.
    • 새로운 차를 추가하기 쉽다는 점은 확장에 열려있다고 볼 수 있다.
  • 다만, CarPartsFactory 는 관점에 따라 하나의 클래스에서 여러가지 일을 한다고 볼 수도 있다.
    • EngineFactory, TireFactory 등으로 더 나뉘어도 되긴 한다.

다이어그램 살펴보기

팩토리 메서드 패턴과 비교해보기

  • 둘 다 객체를 만드는 과정을 추상화시킨 것이다.
  • 둘은 관점이 다르다.
    • 팩토리 메서드 패턴은 팩토리를 구현하는 방법(inheritance) 에 초점을 둔다.
      • 하나의 팩토리 메서드를 어떻게 구현할 것인가?
    • 추상 팩토리 패턴은 팩토리를 사용하는 방법(composition) 에 초점을 둔다.
      • 관련 있는 객체들을 어떻게 생성할 것인가?
  • 둘은 목적이 다르다.
    • 팩토리 메서드 패턴은 구체적인 객체 생성 과정을 하위 또는 상위 클래스로 옮기는 것이 목적
      • ConcreteClass 를 구현하는 것에 목적을 둠
      • 상속의 관점
    • 추상 팩토리 패턴은 관련있는 여러 객체를 구체적인 클래스에 의존하지 않고 만들 수 있게 하는 것이 목적
      • ConcreteClass 구현 자체보다는 클라이언트에서 추상화된 팩토리를 사용하는 것에 더 초점을 맞춤
      • 구성의 관점

추상 팩토리 패턴의 용례

추상 팩토리 패턴의 용례에 대해 알아보자.

DocumentBuilderFactory

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/main/resources/config.xml"));
System.out.println(document.getDocumentElement());
  • DocumentBuilderFactory 추상 클래스는 추상 메서드인 newDocumentBuilder() 를 통해 DocumentBuilder 를 제공하는 것에 관심이 있다.
  • 팩토리 메서드 패턴과 비교하자면, 어떻게 제공 메서드를 구현할 것이냐보다도 그냥 어떤 종류의 DocumentBuilder 를 제공할 것이냐에 관심이 있다.
  • 이와 비슷한 종류로 XPathFactory, TransformerFactory 가 있다.

FactoryBean

  • FactoryBean 은 스프링의 인터페이스로 보통 new 키워드로 간단히 생성하기 힘든 객체가 있을 때 이를 이용한다.
public class CarFactoryBean implements FactoryBean<Car> {
    private final CarFactory carFactory = new CarFactory(new K9PartsFactory());

    @Override
    public Car getObject() throws Exception {
        return carFactory.createCar();
    }

    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }
}

@Configuration
public class FactoryBeanConfig {
    @Bean
    public CarFactoryBean carFactory() {return new CarFactoryBean();}
}

public class FactoryBeanExample {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(FactoryBeanConfig.class);
        Car bean = applicationContext.getBean(Car.class);
        System.out.println(bean);
    }
}
  • CarFactoryBean 의 구현을 보면, Bean 으로 등록되기 위해 필요한 메서드들이 몰려있는 것을 볼 수 있다.
    • getObject() 와 getObjectType() 을 꼭 구현해야 한다.
    • FactoryBean 인터페이스는 어떤 메서드들의 구현을 조합해야 Bean 을 생성할 수 있는지에 관심이 있다.
  • 실제로 FactoryBeanConfig 에서 등록한 Bean 은 CarFactoryBean 인데 애플리케이션 컨텍스트에서 등록한적 없는 Car 타입의 빈을 잘 찾아낸다.
    • 스프링이 FactoryBean 을 인식하고 FactoryBean 의 로직에 따라 Bean 을 잘 만들어주었기 때문이다.

레퍼런스

https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard

반응형
저작자표시 비영리 (새창열림)

'Java > 자바 디자인 패턴' 카테고리의 다른 글

프로토타입 패턴 (Prototype Pattern) 이란?  (2) 2023.01.28
빌더 패턴 (Builder Pattern) 이란?  (0) 2023.01.26
팩토리 메서드 패턴 (Factory Method Pattern) 이란?  (0) 2023.01.23
싱글톤 패턴 (Singleton Pattern) 이란?  (0) 2023.01.20
자바 믹스인(mixins)이란?  (0) 2021.12.30
    'Java/자바 디자인 패턴' 카테고리의 다른 글
    • 프로토타입 패턴 (Prototype Pattern) 이란?
    • 빌더 패턴 (Builder Pattern) 이란?
    • 팩토리 메서드 패턴 (Factory Method Pattern) 이란?
    • 싱글톤 패턴 (Singleton Pattern) 이란?
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바