전체 글

개발자 린다씨
👶 TypeScript

디자인 패턴 - 팩토리 패턴(factory pattern)

팩토리 패턴(factory pattern) 팩토리 패턴(factory pattern)은 어떤 객체를 만들지를 전적으로 팩토리에 위임합니다. 예시를 위해 빵(bread) 팩토리를 만들어보겠습니다. 먼저 Bread라는 타입을 정의하고 세 종류의 빵을 구현합니다. type Bread = { kind: string } class FranceBread implements Bread { kind = 'Baguette' } class IndeaBread implements Bread { kind = 'Flatbread' } class DanishBread implements Bread { kind = 'Ryebread' } 이 예에선 type을 사용했는데, type 대신 인터페이스를 사용해도 됩니다:) 이제 빵 팩토..

👶 TypeScript

final 클래스 흉내 내기

final 클래스 흉내 내기 TypeScript는 클래스나 메서드에 final 키워드를 지원하지 않지만 클래스에서 final의 효과를 흉내내기 어렵지 않습니다. final 키워드는 클래스나 메서드를 확장하거나 오버라이드할 수 없게 만드는 기능입니다. TypeScript에선 비공개 생성자(private constructor)로 final 클래스를 흉내 낼 수 있습니다. class MessageQueue { private constructor(private message: string[]) {} } 생성자를 private으로 선언하면 new로 인스턴스를 생성하거나 클래스를 확장할 수 없게 됩니다. class MessageQueue { private constructor(private message: stri..

👶 TypeScript

데코레이터(decorator)

데코레이터(decorator) 데코레이터(decorator)는 TypeScript의 실험적 기능으로 클래스, 클래스 메서드, 프로퍼티, 메서드 매개변수를 활용한 메타 프로그래밍에 깔끔한 문법을 제공합니다. 데코레이터는 장식하는 대상의 함수를 호출하는 기능을 제공하는 문법입니다. 예제를 통해 데코레이터가 어떻게 동작하는지 알아보겠습니다. @serializable class APIPayload { getValue(): Payload { // ... } } 클래스 데코레이터인 @serializable은 APIPayload 클래스를 감싸고 있으며 선택적으로 이를 대체하는 새 클래스를 반환합니다. 데코레이터를 사용하지 않고 같은 기능을 아래처럼 구현할 수도 있습니다. let APIPayload = serializ..

👶 TypeScript

믹스인(mixin)

믹스인(mixin) JavaScript와 TypeScript는 trait이나 mixin 키워드를 제공하지 않지만 쉽게 직접 구현할 수 있습니다. 두 키워드 모두 둘 이상의 클래스를 상속받는 다중 상속(multiple inheritance)과 관련된 기능을 제공하며, 역할 지향 프로그래밍(role-oriented programming)을 제공합니다. 역할 지향 프로그래밍에선 "이것은 Shape이에요"라고 표현하는 대신 "측정할 수 있어요", "반지름을 가지고 있어요"처럼 속성을 묘사하는 방식을 사용합니다. 즉, "is-a" 관계 대한 'can', 'has-a' 관계를 사용합니다. 믹스인을 구현해 보겠습니다. 믹스인이란 동작과 프로퍼티를 클래스로 혼합(mix)할 수 있게 해주는 패턴으로, 다음 규칙을 따릅니..

👶 TypeScript

다형성

다형성 함수와 타입처럼, 클래스와 인터페이스도 기본값과 상한/하한 설정을 포함한 다양한 제네릭 타입 매개변수 기능을 지원합니다. 제네릭 타입의 범위는 클래스나 인터페이스 전체가 되게 할 수도 있고 특정 메서드로 한정할 수도 있습니다. class FirstMap{ // ① constructor(initialKey: K, initialValue: V){ // ② // ... } get(key: K): V { // ③ // ... } set(key: K, value: V){ // ... } merge(map: FirstMap): FirstMap{ // ④ // ... } static of(k: K, v: V): FirstMap{ // ⑤ // ... } } class와 함께 제네릭을 선언했으므로 클래스 전체에..

👶 TypeScript

클래스는 값과 타입을 모두 선언한다

클래스는 값과 타입을 모두 선언한다 TypeScript의 거의 모든 것은 값 아니면 타입입니다. // 값 let a = 1999 function b(){} // 타입 type a = number interface b { (): void } 값과 타입은 TypeScript에서 별도의 네임스페이스에 존재합니다. 용어를 어떻게 사용하는지를 보고 TypeScript가 알아서 이를 값 또는 타입으로 해석합니다. // 값 let a = 1999 function b(){} // 타입 type a = number interface b { (): void } if(a + 1 > 3){ // 문맥상 값 a로 추론 let x: a = 3 // 문맥상 타입 a로 추론 } 문맥을 파악해 해석하는 이 기능은 정말 유용합니다. 한..

👶 TypeScript

클래스는 구조 기반 타입을 지원한다

클래스는 구조 기반 타입을 지원한다 TypeScript는 클래스를 비교할 때 다른 타입과 달리 이름이 아니라 구조를 기준으로 삼습니다. 클래스는 자신과 똑같은 프로퍼티와 메서드를 정의하는 기존의 일반 객체를 포함해 클래스의 형태를 공유하는 다른 모든 타입과 호환됩니다. 예를 들어 TypeScript에선 Zebra를 인수로 받는 함수에 Poodle을 전달한다고 해서 반드시 에러를 발생시키진 않기 때문입니다. class Zebra { trot(){ // 블라블라 } } class Poodle { trot() { // 여기도 블라블라 } } function ambleAround(animal: Zebra){ animal.trot() } let zebra = new Zebra let poodle = new Poo..

👶 TypeScript

인터페이스 구현 VS 추상 클래스 상속

인터페이스 구현 VS 추상 클래스 상속 인터페이스 구현은 추상 클래스 상속과 아주 비슷합니다. 하지만 인터페이스가 더 범용으로 쓰이며 가벼운 반면, 추상 클래스는 특별한 목적과 풍부한 기능을 갖는다는 점이 다릅니다. 인터페이스 인터페이스는 형태를 정의하는 수단입니다. 값 수준에서 이는 객체, 배열, 함수, 클래스, 클래스 인스턴스를 정의할 수 있다는 뜻입니다. 인터페이스는 아무런 JavaScript 코드를 만들지 않으며 컴파일 타임에만 존재합니다. 추상 클래스 추상 클래스는 오직 클래스만 정의할 수 있습니다. 예상할 수 있겠지만 추상 클래스는 런타임의 JavaScript 클래스 코드를 만듭니다. 추상 클래스는 생성자와 기본 구현을 가질 수 있으며 프로퍼티와 메서드에 접근 한정자를 지정할 수 있습니다. 위..

👶 TypeScript

인터페이스 구현

구현 클래스를 선언할 때 implements라는 키워드를 이용해 특정 인터페이스를 만족 시킴을 표현할 수 있습니다. 다른 명시적인 타입 어노테이션처럼 implements로 타입 수준의 제한을 추가하면 구현에 문제가 있을 때 어디가 잘못되었는지 쉽게 파악할 수 있습니다. 또한 어댑터(adapter), 팩토리(factory), 전략(strategy) 등 흔한 디자인 패턴을 구현하는 대표적인 방식이기도 합니다. implements는 아래처럼 사용할 수 있습니다. interface Animal { eat(food: string): void sleep(hours: number): void } class Dog implements Animal { eat(food: string){ console.info('Ate s..

개발자 린다씨
Cozy_Linda