코딩에 도움이 되는 요소/디자인 패턴
[디자인 패턴] 가상의 생성자를 두어서 관리하자!! 팩토리 메서드 패턴
너어디사니
2024. 5. 3. 19:50
- 의도
- 가상의 생성자를 두어서 따로 관리하는 방법
- 부모 클래스에서 객체들을 생성할 수 있는 Interface를 제공하지만 자식 클래스들이 생성될 객체들의 유형을 변경할 수 있도록 하는 생성 패턴
- 문제
- 하나의 클래스이 모든 함수나 객체가 구현되어 있는 경우 추후에 많은 코드들이 추가 될 경우 추가 수정이 어려워짐은 물론 가독성이 떨어질 수도 있다
- 구현 방법
- 모든 자식 클래스는 같은 Interface를 따르도록 설계를 진행한다 따라서 Interface는 모든 자식 클래스에서 의미가 있는 메서드를 선언한다
- Interface에 공통 함수에는 반환 값이 생성자 Interface를 받도록 구현을 한다
- 자식 클래스가 상속을 받으면서 생성자 Interface를 리턴 받을 수 있도록 구현한다
- 장점
- Interface와 자식 클래스가 단단하게 결합되어있지 않아 보다 유연한 코드 구성이 가능하다
- 단일 책임 원칙의 자식 클래스 코드를 프로그램의 한 위치로 이동을 하여 코드를 조금 더 쉽게 유지 보수 할 수 있다
- 개방 / 폐쇄 원칙을 지키면서 기존의 클라이언트 코드를 훼손하지 않고 새로운 유형의 제품들을 프로그램에 도입할 수 있다
- 단점
- 패턴을 구현하기 위해서 새로운 자식 클래스들을 도입해야 하므로 코드가 더 복잡해질 가능성이 있다
- 자식 Interface들의 기존 계층구조의 패턴을 도입하는 것이 가장 좋다
- 구조(회사 기준)
- 제품에 대한 Interface를 선언한다
interface Product {
fun name()
}
- 원하는 제품을 Product Interface를 사용하여 구현해준다
class Music:Product {
override fun name() {
println("음악")
}
}
// -----------------------------
class Video:Product {
override fun name() {
println("비디오")
}
}
- 제품을 만드는 객체 반환하는 Interface를 생성해준다
- 이 때 만들 제품을 반환하는 함수를 만든다
interface Create {
fun product(): Product
}
- 만들 제품을 클래스로 만들고 상속을 시켜준다
class CreateMusic:Create {
private val music = Music()
override fun product(): Product {
return music
}
}
// -----------------------------
class CreateVideo:Create {
private val video = Video()
override fun product(): Product {
return video
}
}
- 클래스 다이어그램으로 보는 예시
- 적용 예시
- 코드가 함께 작동해야 하는 객체들의 정확한 유형들과 의존관계들을 미리 모르는 경우
- 생성자 코드를 따로 분리하여 나머지 코드와는 독립적으로 확장하기 쉬워진다
- 라이브러리 또는 프레임워크 사용자들에게 내부 컴포넌트들을 확장하는 방법을 제공하고 싶을 때 사용한다
- 프레임워크 전체에서 컴포넌트들을 생성하는 코드를 단일 팩토리 메서드로 줄인 후에 누구나 이 펙토리 메서드를 Override를 할 수 있도록 한다
- 기존 객체들을 매번 재구축하는 대신 이들을 재사용하여 시스템 리소스를 절약하고 싶을 때
- 기존 객체를 재사용 하려면??
- 먼저 생성된 모든 객체를 추적하기 위해 일부 스토리지를 생성
- 누군가가 객체를 요청하면 프로그램은 해당 풀 내에서 Public 객체를 찾아야 한다
- … 이 객체를 클라이언트 코드에 반환
- Public 객체가 없으면, 프로그램은 새로운 객체를 생성 (그리고 풀에 이 객체를 추가)
- 사용이 굉장히 복잡히지지만 팩토리 메서드 패턴을 사용하면 이러한 리소스를 최대한 절약하면서 구현할 수 있다
- 기존 객체를 재사용 하려면??
- 코드가 함께 작동해야 하는 객체들의 정확한 유형들과 의존관계들을 미리 모르는 경우