TypeScript-Factory Pattern with Generics(디자인 패턴)

hannah·2023년 9월 28일
0

JavaScript

목록 보기
110/121

Factory Pattern with Generics

객체를 생성하는 인터페이스만 미리 정의하고, 인스턴스를 만들 클래스의 결정은 서브 클래스가 내리는 패턴이다.

  • 여러 개의 서브 클래스를 가진 슈퍼 클래스가 있을 때, 입력에 따라 하나의 서브 클래스의 인스턴스를 반환한다.
  • 이 디자인 패턴은 객체의 생성과정을 캡슐화하여 클라이언트 코드와의 결합도를 낮추고, 유연성과 확장성을 높이는데 도움을 준다.

아래의 코드는 일반적인 팩토리 패턴을 사용했다. 실제로 객체를 생성하는 CarFactory 클래스에 인스턴스 메서드를 전역멤버로 구현했다. CarFactory.getInstance()함수를 호출할 때 생성시키고자 하는 타입에 따라 생성되는 클래스를 반환한다. 이렇게 구현함으로써 Bus, Taxi 클래스를 new instance화 하지 않고도 객체를 생성할 수 있다.

interface Car {
    drive(): void;
    park(): void;
}
 
class Bus implements Car {
    drive(): void {}
    park(): void {}
}
 
class Taxi implements Car {
    drive(): void {}
    park(): void {}
}
 
class CarFactory {
    static getInstance(type: String): Car {
        // car의 type이 추가될 때마다, case 문을 추가해야 하는 단점
        switch (type) {
            case "bus":
                return new Bus();
            default:
                return new Taxi();
        }
    }
}
 
const bus = CarFactory.getInstance("bus");
const taxi = CarFactory.getInstance("taxi");

하지만 위의 코드에서는 Car 타입이 추가될 때 마다 case 문을 추가해야 하는 단점이 있다. 이러한 단점을 보완하고자 제너릭을 활용하여 팩토리 패턴을 구현해보자.


interface Car {
    drive(): void;
    park(): void;
}
 
class Bus implements Car {
    drive(): void {}
    park(): void {}
}
 
class Taxi implements Car {
    drive(): void {}
    park(): void {}
}
 
class Suv implements Car {
    drive(): void {}
    park(): void {}
}
 
class CarFactory {
    static getInstance<T extends Car>(type: { new (): T}): T {
        return new type();
    }
}
 
const bus = CarFactory.getInstance(bus);
const taxi = CarFactory.getInstance(taxi);

이전 코드와 다른 점은 getInstance 메서드에 Car 인터페이스를 제약조건으로 가지는 제너릭으로 선언했다. 이렇게 선언함으로써 getInstance의 메서드에 별도의 내부로직 코드 수정 없이 Car 인터페이스를 implements한 모든 Car타입을CarFactory.getInstance() 함수에 인수값을 호출하여 각각 객체를 생성할 수 있게 되었다.

0개의 댓글