"JavaScript Design Pattern" 포스팅은 ChatGPT에게 "Essential design patterns for JavaScript developers to learn"로 질문한 뒤 나온 내용에 대해 정리하는 포스팅입니다.
1. 팩토리 패턴(Factory Pattern)
팩토리 패턴은 생성할 객체의 정확한 클래스나 생성자 함수를 지정하지 않고도 객체를 생성할 수 있는 방법을 제공하는 생성 패턴이다.
팩토리 패턴은 객체를 생성하기 위한 일반 인터페이스를 제공하고 하위 클래스가 생성될 객체의 유형을 변경할 수 있도록 한다.
팩토리 패턴은 다음과 같은 이점을 제공한다.
- 캡슐화: 객체 생성이 애플리케이션의 로직과 분리되어 보다 모듈화 되고 유지 관리가 용이한 아키텍처를 제공한다.
- 유연성: 팩토리 패턴을 사용하면 새 구현 클래스를 추가하기만 하면 새 객체를 쉽게 생성할 수 있다.
- 추상화: 팩토리 패턴은 객체 생성을 위한 높은 수준의 인터페이스를 제공하며 구현 세부 사항을 클라이언트 코드에서 숨길 수 있다.
JavaScript에서 팩토리 패턴은 함수나 객체를 사용하여 구현할 수 있다.
두 경우 모두 매개변수 집합 또는 configuration 옵션을 기반으로 다른 객체를 생성하고 반환할 수 있는 함수 또는 객체를 생성하는 것이 핵심이다.
JavaScript에서 팩토리 패턴의 가장 기본적인 구현은 팩토리 함수를 사용하는 것이다. 팩토리 함수는 전달된 인수를 기반으로 새 객체를 생성하고 반환하는 일반 함수이다.
다음은 팩토리 함수의 예이다:
function createPerson(name, age) {
return {
name: name,
age: age,
sayHello: function() {
console.log("Hello, my name is " + this.name);
}
};
}
const person1 = createPerson("Alice", 30);
const person2 = createPerson("Bob", 25);
person1.sayHello(); // output: Hello, my name is Alice
person2.sayHello(); // output: Hello, my name is Bob
이 예제에서 createPerson 함수는 두 개의 인자 name과 age를 받는 팩토리 함수로, name과 age 속성을 가진 새 객체와 sayHello() 메서드를 반환한다.
JavaScript에서 팩토리 메서드를 구현하는 또 다른 방법은 팩토리 객체를 사용하는 것이다.
이 경우 팩토리 객체는 다양한 유형의 객체를 생성하는 메서드가 있는 객체이다. 각 메서드에는 생성할 객체의 특성을 정의하는 매개변수 집합이 사용된다.
다음은 팩토리 객체의 예이다:
const carFactory = {
createCar: function(model, year, color) {
return {
model: model,
year: year,
color: color,
start: function() {
console.log("Starting " + this.model);
},
stop: function() {
console.log("Stopping " + this.model);
}
};
}
};
const car1 = carFactory.createCar("Ford Mustang", 2022, "red");
const car2 = carFactory.createCar("Tesla Model S", 2021, "white");
car1.start(); // output: Starting Ford Mustang
car2.stop(); // output: Stopping Tesla Model S
이 예제에서 carFactory는 새 자동차 객체를 생성하는 createCar() 메서드가 있는 팩토리 객체이다.
createCar() 메서드는 model, year, color의 세 가지 인수를 받고, 이러한 속성과 start() 및 stop() 메서드를 가진 새 객체를 반환한다.
JavaScript에서 팩토리 패턴을 사용할 때의 주요 장점 중 하나는 객체 생성 로직을 캡슐화할 수 있어 생성할 수 있는 객체 유형을 더 쉽게 수정하거나 확장할 수 있다는 점이다.
2. Factory Pattern 연습 코드
ChatGPT에게 "Give me a challenge to practice the Factory Pattern in JavaScript."라고 질문한 뒤 나온 문제와 그에 대한 답이다.
스켈레톤 코드는 다음과 같다.
// 요리 유형 정의
const DISH_TYPES = {
BURGER: 'burger',
PIZZA: 'pizza',
PASTA: 'pasta'
};
// 각 요리 유형에 사용 가능한 토핑과 소스 정의
const TOPPINGS = {
[DISH_TYPES.BURGER]: ['lettuce', 'tomato', 'cheese', 'bacon'],
[DISH_TYPES.PIZZA]: ['mushrooms', 'olives', 'peppers', 'sausage'],
[DISH_TYPES.PASTA]: ['meatballs', 'mushrooms', 'tomato sauce', 'cream sauce']
};
const SAUCES = {
[DISH_TYPES.BURGER]: ['ketchup', 'mayonnaise', 'mustard'],
[DISH_TYPES.PIZZA]: ['tomato sauce', 'bbq sauce', 'ranch'],
[DISH_TYPES.PASTA]: ['tomato sauce', 'cream sauce', 'pesto']
};
// DishFactory 클래스 정의
class DishFactory {
// 생성 메서드를 구현
// 요리 유형, 토핑, 소스를 받아야 함
// 요리 유형이 유효하고 토핑/소스가 요리 유형에 유효하면 요리 객체를 반환
// 그렇지 않으면 null 또는 오류 메시지를 반환
}
// Usage
const dishFactory = new DishFactory();
// Create a burger with lettuce, tomato, cheese and ketchup
const burger = dishFactory.create(DISH_TYPES.BURGER, ['lettuce', 'tomato', 'cheese'], ['ketchup']);
console.log(burger); // { type: 'burger', toppings: ['lettuce', 'tomato', 'cheese'], sauces: ['ketchup'] }
// Create a pasta with meatballs, tomato sauce and cream sauce
const pasta = dishFactory.create(DISH_TYPES.PASTA, ['meatballs'], ['tomato sauce', 'cream sauce']);
console.log(pasta); // { type: 'pasta', toppings: ['meatballs'], sauces: ['tomato sauce', 'cream sauce'] }
// Try to create a salad with cheese and ranch (invalid dish type and invalid sauce for pizza)
const salad = dishFactory.create('salad', ['cheese'], ['ranch']);
console.log(salad); // null or an error message
이를 구현한 코드는 다음과 같다.
// 요리 유형 정의
const DISH_TYPES = {
BURGER: 'burger',
PIZZA: 'pizza',
PASTA: 'pasta',
};
// 각 요리 유형에 사용 가능한 토핑과 소스 정의
const TOPPINGS = {
[DISH_TYPES.BURGER]: ['lettuce', 'tomato', 'cheese', 'bacon'],
[DISH_TYPES.PIZZA]: ['mushrooms', 'olives', 'peppers', 'sausage'],
[DISH_TYPES.PASTA]: ['meatballs', 'mushrooms', 'tomato sauce', 'cream sauce'],
};
const SAUCES = {
[DISH_TYPES.BURGER]: ['ketchup', 'mayonnaise', 'mustard'],
[DISH_TYPES.PIZZA]: ['tomato sauce', 'bbq sauce', 'ranch'],
[DISH_TYPES.PASTA]: ['tomato sauce', 'cream sauce', 'pesto'],
};
// DishFactory 클래스 정의
class DishFactory {
// 생성 메서드를 구현
// 요리 유형, 토핑, 소스를 받아야 함
// 요리 유형이 유효하고 토핑/소스가 요리 유형에 유효하면 요리 객체를 반환
// 그렇지 않으면 null 또는 오류 메시지를 반환
create(dishType, toppings, sauces) {
if (!Object.values(DISH_TYPES).includes(dishType)) {
console.error('존재하지 않는 요리 유형입니다.');
return null;
}
if (!toppings.every((topping) => TOPPINGS[dishType].includes(topping))) {
console.error('요리 유형에 맞지 않는 토핑입니다.');
return null;
}
if (!sauces.every((sauce) => SAUCES[dishType].includes(sauce))) {
console.error('요리 유형에 맞지 않는 소스입니다.');
return null;
}
return {
type: dishType,
toppings,
sauces,
};
}
}
// Usage
const dishFactory = new DishFactory();
// Create a burger with lettuce, tomato, cheese and ketchup
const burger = dishFactory.create(
DISH_TYPES.BURGER,
['lettuce', 'tomato', 'cheese'],
['ketchup']
);
console.log(burger); // { type: 'burger', toppings: ['lettuce', 'tomato', 'cheese'], sauces: ['ketchup'] }
// Create a pasta with meatballs, tomato sauce and cream sauce
const pasta = dishFactory.create(
DISH_TYPES.PASTA,
['meatballs'],
['tomato sauce', 'cream sauce']
);
console.log(pasta); // { type: 'pasta', toppings: ['meatballs'], sauces: ['tomato sauce', 'cream sauce'] }
// Try to create a salad with cheese and ranch (invalid dish type and invalid sauce for pizza)
const salad = dishFactory.create('salad', ['cheese'], ['ranch']);
console.log(salad); // null or an error message
'Web > JS' 카테고리의 다른 글
[JS] 디자인 패턴(Design Pattern)_데코레이터 패턴(Decorator Pattern) (0) | 2023.02.26 |
---|---|
[JS] 디자인 패턴(Design Pattern)_옵저버 패턴(Observer Pattern) (0) | 2023.02.25 |
[JS] 디자인 패턴(Design Pattern)_싱글톤 패턴(Singleton Pattern) (0) | 2023.02.20 |
[JS] 디자인 패턴(Design Pattern)_공개 모듈 패턴(Revealing Module Pattern) (0) | 2023.02.18 |
[JS] 디자인 패턴(Design Pattern)_모듈 패턴(Module Pattern) (0) | 2023.02.16 |