팩토리 패턴

존스노우·2024년 4월 21일
0

디자인패턴

목록 보기
3/4

new

  • 특정 구현을 바탕으로 프로그램을 하면 않아야 된다.
  • new DecoyDuck() 등
  • 변경이나 추가 요구사항시 OCP 원칙에 위반이 된다.

변화

  • 인터페이스에 맞춰서 코딩하자 변화에 대응하게 왜?
  • 다형성 특징 때문.
  • 구상클래스 많이 사용시 새로운 구상 클래스마다 코드 고쳐야됨.. 위에 처럼 OCP 위반

피자코드 예시

  • 가장 문제되는 부분. 인스턴스를 만드는 구상 클래스 선택하는 부분
  • 종류나 추가 될때마다 계속 고쳐야지

객체 생성 부분 캡슐화

  • 객체 생성 코드만 따로 빼서 피자 객체 만드는일 전담 하자
  • 새로 만들 클래스를 팩토리로 명
  • 객체 생성 처리 클래스를 팩토리라 함.
  • 이런 식으로 피자 가격 설명하는 PizzaShopMenu 클래스 HomeDelivery 클래스 도
  • 팩토리 응용 가능

장점은 ?

  • 구현을 변경할때 팩토리 클래스 하나만 고치면 됨.

정적 메소드로 선언한 디자인이랑 차이 ?

  • 정적 팩토리 메서드, 객체의 인스턴스를 따로 만들지 않아도됨
  • 서브클래스를 만들어 객체 생성 메소드의 행동 변경하지 못하는 단점이 존재.. 으음

간단한 팩토리의 정리

  • 프로그래밍에 쓰이는 관용구에 가까움.
  • 정확하게는 패턴은 아님..

추가

디자인 패턴을 얘기할때 인터페이스를 구현한다라는 표현이 나온다고 해서 항상 클래스를 선언하는 부분에 IMPLEMENTS 키워드를 써서 어떤 자바 인터페이스를 구현하는 클래스를 만든다고 생각하면 안됩니다 일반적으로 어떤상위 형식(클래스와 인터페이스)에 있는 구상 클래스는 그 상위 형식의 인터페이스를 구현하는 클래스라고 생각하면됩니다

  • 여기서 "인터페이스"는 좀 더 추상적인 의미로 사용?

  • 어떤 클래스가 상위 클래스나 인터페이스에서 정의된 메서드와 속성을 가지는 것을 의미

  • 결론적으로 단순히 IMPLEMENT가 아니라 인터페이스의 메서드를 오버라이딩에서 구현
    한다 라는 의미도 있다

  • 이런 의미..

다양한 팩토리 만들기 ( 피자 프랜차이즈 사업)

  • 기존 심플팩토리로 구현을 하면?

  • 그러나 굽는 방식이 달라지거나 피자를 자르는걸 까먹거나 문제가 생김.

  • PizzaStore와 피자 제작 코드를 하나로 묶어주는 프레임워크를 만들어야됨.

피자가게 프레임 워크

서브클래스 결정?

  • 각 지점마다 달라질 수 있는 것은 피자 스타일

  • createPizza() 메소드에서 각 스타일에 맞는 피자 메서드를 만들자

  • orderPiza도 서브클래스에서 구현되기때문에 어떤 피자를 만드는지 모름 알수 없음

  • Pizza는 추상클래스라 어떤 구상클래스에서 작업 처리되는지 알수 없다.

  • 결론적으로 PizzaStore와 Pizza는 서로 분리 되어있음

  • 으음 PizzStore도 추상 Pizza도 추상 인터페이스로도 바꿀 수 있겠지

  • 캡슐화? 캡슐화는 추상클래스 혹은 인터페이스로?

피자스타일 서브 클래스 만들기

  • 상속받은 슈퍼클래스의 추상 메서드를 정의한다

  • 여기서 Pizza도 추상 메서드드 이기 때문에 NY스타일에맞는 Pizza구현체도 정의해줘야 된다.

  • 이런식으로..

  • 슈퍼클래스에 orderPizza() 메소드에는 어떤 피자가 만들어지는지 전혀 알수 없음.

  • 구현 클래스에서 정의된 피자 준비 굽고 자르고 포장하기만..

팩토리 메서드 선언하기

  • 피자 객체 인스턴스 만드는 일? PizzaStore의 서브 클래스 에서!
  • 팩토리 메서드는 객체 생성을 서브클래스에서 캡슐화.
  • 그러면 슈퍼클래승에있는 클라이언트 코드와 서브클래스에 있는 객체 생성 코드 분리

팩토리 메소드 패턴 살펴보기


  • 팩토리 패턴은 객체 생성을 캡슐화함 (여기선 PizzaStore , Pizza)

  • 여기까지와서 생각을 정리해보면

  • 슈퍼클래스는 어떤 객체를 어떻게 만들지 정의

  • 위에 캡슐화한 객체를 가지고 의존성을 분리

  • 번뜩이는 이해 문장이 생각낫는데 순식간에 사라져서 말이 이상하게 됫네 ㅠㅠ

  • 최종적으로 추상클래스로 의존성을 약하게하고

  • 구상클래스들이 직접적인 구현을한다. 하.. 쉽게 설명하고싶다.

  • 팩토리 메소드는 이런 방법으로 캡슐화 있어 핵심적인 역할.

팩토리 메서드 패턴의 정의

팩토리 메소드 패턴 에서 객체를 생성할 때 필요한 인터페이스를 만듬.
어떤 클래스의 인스턴스를 만들어지는 서브클래스에서 결정함
팩토리 메소드 패턴을 사용하면 클래스 인스턴스를 만드는 일을 서브클래스에게 맡기게 됩니다.

  • 팩토리 메소드 패턴으로 구상형식 인스턴스를 만드는 작업을 캡슐화 가능

팩토리 메소드 패턴에서는 어떤클래스의 인스턴스를 만들지 서브클래스가 결정한다

  • 결정한다? 실행 중 서브클래스에서 어떤 클래스의 인스턴스를 만들지
  • 결정해서가 아니라 생산자 클래스가 실제 생산될 제품을 전혀모르는 상태로 만들어진다
  • 정확히는 사용하는 서브클래스에 따라 생산되는 객체 인스턴스가 결정 된다.

객체 의존성

  • 구상 클래스에 직접 의존하게되면 변경에 취약하게 된다.

의존성 뒤집기 원칙 (의존성 역전의 법칙)

  • 추상화된 것에 의존하게만들고 구상 클래스에 의존하지 않는다.
  • 고수준 구성 요소가 저수준 구성요소에 의존하면 안된다
  • 항상 추상화에 의존하게 만들어야된다.
  • 의존성 역전법칙 설명에 항상 나오는 내용..

의존성 뒤집기 원칙 적용

  • 기존 PizzaStore은 모든 종류의 피자에 의존함.

  • orderPizza 메소드에 구상 형식의 인스턴를 직 접 만들기 때문

  • Pizza를 추상 클래스로 만들었으나 이 코드에서 구상 피자객체를 생성하는 것은 아니기에 추상화로 얻는 것이 별로 없다

  • 인스턴스 만드는 부분을 orderPizza()에서 뽑아낼까?

  • 팩토리 메서드 패턴으로 인스턴스 만드는 부분을 뽑아내자.

  • 여기서 나오는 내용은 단순 Pizaa를 추상클래스로 선언하기만해서는 안되고

  • 팩토리 메소드 패턴으로 인스턴스를 만드는 부분을 만들어서 작성하는 것ㅅ일듯.

  • 그림에서도 기존 한 방향으로 향했던 화살이 Pizza라는 추상화에 의존하고 방향이 역전됨.

  • 의존성 역전의 법칙이다.

의존성 뒤집기 원칙을 지키는 방법

  • 변수에 구상 클래스의 래퍼런스를 저장하지말자 (바로 구상클래스를 선언하지말고 추상화된 변수로 선언하는 의미 Pizza pizza = new CheezePizza; 이런식

  • 구상 클래스에서 유도된 클래스를 만들지 말자 ( 인터페이스나 추상클래스처럼 추상화된 것으로 부터 클래스를 만듬)

  • 베이스 클래스에 이미 구현되어있는 메소드를 오버라이드 금지 (추상메서드가 아닌 공통으로 사용하는 함수 이미 구현되있는함수를 오버라이드하지말자는의미같음)

  • 이러한 방식은 항상 지켜야하는 규칙이 아니라 지향해야 할 바를 알려 줌.

원재료 종류 알아보기

원재료군으로 묶자

  • 뉴욕과 시카고 사용하는 재료는 서로 다름
  • 각 재료를 묶어서 판매해야지..

원재료 팩토리 만들기


  • 각 재료 별 생성 메소드 정의

  • 피자 재료 펙토리 인터페이스에 리턴타입 재료들도 다 추상화 인터페이스로 구현되있다.

  • 각 피자는 재료팩토리가 만들어졌으니 재료 팩토리를 생성자로 받는다.

  • 각 피자마다 선택한 재료를 팩토리를 통해 생성한다.

  • 이에 맞추어 피자도 기존 String 타입에서 각 재료별 타입을 바꾸고

  • 마지막 toString 메소드에서 어떤피자가 어떤재료로 만들어지는지를 출력한다.

  • 여기 예제들을 통해 어떤 제품을만들때

  • 제품을 추상화(Pizza)하고 구상클래스(cheezePizza)를 만들고

  • 팩토리 메소드 패턴을 이용해 추상화(Pizza)된 제품을을 만드는

  • 함수들을 모아둔 팩토리 클래스를 만든다

  • 결론적으로 추상화된 팩토리 클래스에서 각 여기선 지점에 맞는 재료나 피자를

  • 다형성의 성질을 통해 제공하고 이러한 코드는 앞서나온 의존성 역전 법칙을따르며

  • 수정엔 막혀있고 확장에 열려있는 유연한 코드가 된다.

  • 최종적으로 피자스토어 구상클래스는
  • 재료 팩토리 클래스를 선언해 이런식으로 피자를 만든다.

바뀐 내용 되돌아 보기

  • 추상팩토리라고 부르는 새로운 형식의 팩토리를 도입해서 피자 종류에 맞는

  • 원재료군을 생산하는 방법 구축

  • 제품을 위한? 내가 이해 한 것은 재료 추상팩토리를 볼때 리턴타입이 추상화 된 재료들.. 제품 등.. 아..뭔가 더 깊이 이해하면 뭔가 더 좋을거 같다

  • 피자스토어에선 뉴욕 시카고 피자 이런 것

  • 추상 팩토리로 제품군을 생성하는 인터페이스를 제공하면

  • 코드와 제품을 생산하는 팩토리를 분리 할 수 있음

추상 팩토리 패턴의 정의

추상 팩토리 패턴은 구상 클래스에 의존하지 않고도
서로 연관되거나 의존적인 객체로 이루어진 제품군을 생산하는 인터페이스 제공
구상 클래스는 서브클래스에서 만듭니다


추상 팩토리에 들어있는 각 메소드는 사실 팩토리메서드 ?

  1. 팩토리 메서드 패턴:
  • 객체 생성을 위한 인터페이스를 정의하고, 서브클래스에서 어떤 클래스의 인스턴스를 생성할지 결정
  • 단일 제품 생성에 초점
  • 상속으로 객체를 만듬
  1. 추상 팩토리 패턴:
  • 관련된 객체들의 집합을 생성하기 위한 인터페이스 제공여러 제품군 생성에 초점
    객체 구성을 통해 구현

  • 인터페이스로 구성(COMPOSITION)으로

  • 팩토리 메서드와 다른접은 서로 연관되거나 의존적인 객체로 이루어진 제품군을 생산
  • 팩토리 메서드는 단일 제품 생산에 초점 이다.

예시 코드

팩토리 메서드


profile
어제의 나보다 한걸음 더

0개의 댓글