Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- JPA
- 티스토리챌린지
- JavaSpring
- springboot
- 웹애플리케이션서버
- ReactHooks
- go
- test
- Redux
- Spring
- tanstackquery
- component
- Chakra
- react-hook-form
- java
- golang
- React
- typescript
- 오블완
- css
- javascript
- storybook
- Gin
- hook
- frontend
- satisfiles
- RTK
- backend
- designpatterns
Archives
- Today
- Total
bkdragon's log
팩토리 메서드, 추상 팩토리 패턴 본문
팩토리 메서드 패턴
인스턴스를 생성자 대신 팩토리 클래스의 추상 메서드로 생성하게 하는 패턴. 서브 클래스에서 오버라이드해서 생성 내용을 유연하게 변경할 수 있다.
구성 요소
- Product(제품): 팩토리 메서드에 의해 생성되는 객체의 추상 클래스.
- ConcreteProduct(구체적인 제품): Product의 구현체.
- Creator(창조자): 팩토리 메서드를 선언하는 추상 클래스. 실제 인스턴스를 생성하는 추상 메서드를 가진다.
- ConcreteCreator(구체적인 창조자): Creator의 구현체, 팩토리 메서드를 구현하여 구체적인 인스턴스를 생성한다.
예시 코드
abstract class Animal {
abstract speak(): string;
}
abstract class AnimalFood {
abstract getName(): string;
}
class DogFood extends AnimalFood {
getName(): string {
return "강아지 사료";
}
}
class Dog extends Animal {
food: AnimalFood;
speak(): string {
return "멍멍!";
}
}
class CatFood extends AnimalFood {
getName(): string {
return "고양이 사료";
}
}
class Cat extends Animal {
food: AnimalFood;
speak(): string {
return "야옹!";
}
}
// 추상 팩토리 클래스
abstract class AnimalFactory {
abstract buildAnimal(): Animal;
}
// 구체적인 팩토리 클래스들
class DogFactory extends AnimalFactory {
buildAnimal(): Animal {
const dog = new Dog();
dog.food = new DogFood();
return dog;
}
}
class CatFactory extends AnimalFactory {
buildAnimal(): Animal {
const cat = new Cat();
cat.food = new CatFood();
return cat;
}
}
// 사용 예시
const dog = new DogFactory().buildAnimal(); // type은 Animal
console.log(dog.speak()); // 출력: "멍멍!"
const cat = new CatFactory().buildAnimal(); // type은 Animal
console.log(cat.speak()); //
팩토리 메서드를 통해 생성된 인스턴스는 추상 타입(Animal)으로 반환되지만, 실제로는 구체적인 구현체(Dog, Cat 등)의 모든 기능을 가지고 있다. 다만 해당 구체적인 타입의 고유 메서드를 사용하려면 타입 캐스팅이 필요하다.
const dog = new DogFactory().buildAnimal() as Dog; // 구체적인 Dog 타입으로 캐스팅
dog.food; // DogFood 타입으로 접근 가능
추상 팩토리 패턴
추상 팩토리 패턴은 구체적인 제품을 지정하지 않고 팩토리 메서드 집합의(= 팩토리 메서드를 여러개 가지는) 인터페이스를 정의한다.
구성 요소
- AbstractFactory(추상 팩토리): 팩토리 메서드 집합의 인터페이스.
- ConcreteFactory(구체적인 팩토리): AbstractFactory를 구현하는 구체적인 클래스. 각 팩토리 메서드를 구현하여 구체적인 제품을 생성한다.
- AbstractProduct(추상 제품): 팩토리 메서드에 의해 생성되는 객체의 인터페이스.
- ConcreteProduct(구체적인 제품): AbstractProduct의 구현체.
- Client(클라이언트): ConcreteFactory와 ConcreteProduct를 사용하는 클래스.
추상 팩토리 패턴 예시 코드
// 추상 제품들
interface Animal {
food: AnimalFood;
toy: AnimalToy;
speak(): string;
}
interface AnimalFood {
getName(): string;
}
interface AnimalToy {
play(): string;
}
// 구체적인 제품들 - 강아지 제품군
class Dog implements Animal {
food: DogFood;
toy: DogToy;
speak(): string {
return "멍멍!";
}
}
class DogFood implements AnimalFood {
getName(): string {
return "강아지 사료";
}
}
class DogToy implements AnimalToy {
play(): string {
return "공을 가지고 놀아요";
}
}
// 구체적인 제품들 - 고양이 제품군
class Cat implements Animal {
food: CatFood;
toy: CatToy;
speak(): string {
return "야옹!";
}
}
class CatFood implements AnimalFood {
getName(): string {
return "고양이 사료";
}
}
class CatToy implements AnimalToy {
play(): string {
return "낚싯대 장난감을 가지고 놀아요";
}
}
// 추상 팩토리 (인터페이스)
interface PetFactory<T extends Animal> {
createAnimal(): T;
createFood(): AnimalFood;
createToy(): AnimalToy;
}
// 구체적인 팩토리들
class DogProductFactory implements PetFactory<Dog> {
createAnimal(): Dog {
return new Dog();
}
createFood(): DogFood {
return new DogFood();
}
createToy(): DogToy {
return new DogToy();
}
}
class CatProductFactory implements PetFactory<Cat> {
createAnimal(): Cat {
return new Cat();
}
createFood(): CatFood {
return new CatFood();
}
createToy(): CatToy {
return new CatToy();
}
}
// 클라이언트 코드
class PetShop {
buildAnimal<T extends Animal>(factory: PetFactory<T>): T {
const animal = factory.createAnimal();
animal.food = factory.createFood();
animal.toy = factory.createToy();
return animal;
}
}
const petShop = new PetShop();
const dogShop = petShop.buildAnimal(new DogProductFactory());
const catShop = petShop.buildAnimal(new CatProductFactory());
제네릭을 사용해서 팩토리 메서드 집합의 인터페이스를 정의하고, 클라이언트에서 팩토리를 갈아끼우는 방식으로 확장성을 높였다.
새로운 동물이 추가되면 팩토리 클래스만 추가하고 클라이언트에 넣어주면 된다.
정리
팩토리 메서드 패턴은 하나의 팩토리 메서드를 가지는 반면, 추상 팩토리 패턴은 여러 개의 팩토리 메서드를 가진다.
그래서 단일 제품이 아닌 여러 제품을 생성하는 경우에 추상 팩토리 패턴이 더 적합하다.
'Typescript' 카테고리의 다른 글
싱글톤 패턴 (3) | 2024.11.13 |
---|---|
빌더 패턴 (0) | 2024.11.10 |
Absolute (1) | 2023.10.29 |
ReplaceAll (0) | 2023.10.23 |
문자열의 길이 구하기 (1) | 2023.10.21 |