반응형
팩토리 패턴은 이름처럼, 객체를 생성해주는 패턴을 의미합니다.
공장에서 제품들을 찍어내듯이, 코드 상으로 비슷한 객체를 조건에 맞게 찍어냅니다.
팩토리 패턴의 특징
- 상위 클래스는 클래스의 뼈대를 제공한다. ( 추상 클래스를 사용하곤 합니다. )
- 하위 클래스에서 구체적인 정보를 전달해줍니다.
- 팩토리 함수 or 팩토리 클래스에서 조건에 맞게 객체를 생성해줍니다.
- 상위 클래스에서 주로 로직을 관리하기 때문에 유지보수하기 쉽다는 장점이 있습니다.
타입스크립트를 이용해서 팩토리 패턴 사용해보기 1 ( 추상 클래스 )
type LectureType = 'Database' | 'Algorithm' | 'SelfStudy';
// 상위 클래스 (추상 클래스)
abstract class Lecture {
public abstract getInfo(): string;
}
// 하위 클래스's
class Database extends Lecture {
constructor(private lectureName: string, private duration: number) {
super();
}
public getInfo() {
return '<DB> ' + this.lectureName + ',' + this.duration + 'm';
}
}
class Algorithm extends Lecture {
constructor(private lectureName: string, private duration: number) {
super();
}
public getInfo() {
return '<AG> ' + this.lectureName + ',' + this.duration + 'm';
}
}
class SelfStudy extends Lecture {
constructor(private lectureName: string, private duration: number) {
super();
}
public getInfo() {
return '[SelfStudy]' + this.lectureName + ',' + this.duration + 'm';
}
}
// 팩토리 클래스
class LectureFactory {
static getLecture (type: LectureType, name: string, duration: number) {
if (type === 'Database') {
return new Database(name ,duration)
} else if (type === 'Algorithm') {
return new Algorithm(name, duration);
} else {
return new SelfStudy(name, duration);
}
}
}
// test
const databaseLecture = LectureFactory.getLecture('Database', 'db', 90);
const algorithmLecture = LectureFactory.getLecture('Algorithm', 'ag', 120);
console.log(databaseLecture); // { "lectureName": "db", "duration": 90 }
console.log(algorithmLecture); // { "lectureName": "ag", "duration": 120 }
}
추상 클래스를 사용하면, 하위 클래스 별로 메소드를 오버라이딩해서 별도의 로직을 구현할 수 있습니다.
위의 코드는 공통적인 로직이 많기 때문에 비효율적으로 보이네요..
추상클래스를 사용하지 않고, 다음 코드에서 해결해보도록 하겠습니다.
타입스크립트를 이용해서 팩토리 패턴 사용해보기 2 ( 클래스 )
type LectureType = 'Database' | 'Algorithm' | 'SelfStudy';
// 추상 클래스 대신 일반 클래스
class Lecture {
constructor(private lectureName: string, private duration: number) {}
public getInfo() {
this.lectureName + ',' + this.duration;
}
}
// 하위 클래스's
class Database extends Lecture {
constructor(lectureName: string, duration: number) {
super(lectureName, duration);
}
}
class Algorithm extends Lecture {
constructor(lectureName: string, duration: number) {
super(lectureName, duration);
}
}
class SelfStudy extends Lecture {
constructor(lectureName: string, duration: number) {
super(lectureName, duration);
}
}
// 팩토리 클래스
class LectureFactory {
static getLecture (type: LectureType, name: string, duration: number) {
if (type === 'Database') {
return new Database(name ,duration)
} else if (type === 'Algorithm') {
return new Algorithm(name, duration);
} else {
return new SelfStudy(name, duration);
}
}
}
const databaseLecture = LectureFactory.getLecture('Database', 'db', 90);
const algorithmLecture = LectureFactory.getLecture('Algorithm', 'ag', 120);
console.log(databaseLecture);
console.log(algorithmLecture);
상위 클래스에 공통 프로퍼티 + 공통 메소드를 정의했고, 하위 클래스에서는 불필요한 프로퍼티 + 메소드를 제거했습니다.
추상 클래스를 사용해서 작성한 코드보다 보다 간결해졌습니다 :)
반응형
'TypeScript' 카테고리의 다른 글
[Typescript] 자료구조 : 이중 연결 리스트 (doubly-LinkedList) (0) | 2023.02.19 |
---|---|
[Typescript] 자료구조 : 단방향 연결 리스트 (Singly-LinkedList) (0) | 2023.02.18 |
[Typescript] 디자인 패턴 : 싱글톤 패턴, 정리해보기 (0) | 2023.02.11 |
[Typescript] Mapped Type (매핑된 타입) (0) | 2023.01.07 |
[Typescript] 생성자의 타입을 표현하기 (feat. 생성자 시그니처) (0) | 2023.01.07 |