Factory 패턴

kim yeeun·2023년 10월 17일
0

디자인패턴

목록 보기
1/1

Factory?

먼저 이 패턴에 팩토리(Factory) 라는 이름이 붙은 이유는 공장에서 상품을 생산 하듯이, 팩토리 메서드로 비슷한 객체를 찍어내는 동작을 하기 때문입니다.

Template Method Pattern & Factory Method Pattern

팩토리 패턴 (Factory Pattern)이 아닌 팩토리 메서드 패턴(Factory Method Pattern) 이라고 하는 이유는 이 패턴이 템플릿 메서드 패턴(Template Method Pattern)에서 파생한 것이기 때문입니다.
템플릿 메서드 패턴이란, 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서는 추상 메서드를 통해 구체적인 내용을 결정하도록 하는 디자인 패턴입니다.

이런 구조로 만들게 되면 상위 클래스에서 로직을 공통화 할 수 있다는 장점이 있습니다. 이러한 템플릿 메소드 패턴을 인스턴스 생성에 응용한 것이 팩토리 메서드 패턴입니다.
하지만 JavaScript는 프로타입 기반 언어로, 원래는 Java나 C++ 에서 사용하는 클래스라는 개념이 없습니다. 대신 프로토타입을 이용해 상속을 구현하거나, 혹은 new 키워드와 함수를 이용해 클래스처럼 동작하도록 흉내낼 수 있습니다.
(c.f. ES6에서 추가된 class는 문법적 설탕일 뿐 내부적으로는 ES5 이하에서 prototype을 이용해 구현한 것과 같습니다.)

function Person(name) {
  this.name = name
  this.introduce = function() {
    return 'My name is' + this.name
  }
}

// name 프로퍼티와 introduce 메소드를 미리 초기화한 객체를 리턴합니다.
var user1 = new Person('godori')
var user2 = new Person('irodog')

user1.introduce() // My name is godori
user2.introduce() // My name is irodog

이와 같이 Person이라는 개별 객체를 new 키워드로 생성할 수 있습니다.

JavaScript Factory Function

new 키워드로 객체를 생성하지 않고 ES6의 Object.assign()을 사용해서 팩토리 함수를 구현해 보겠습니다. 이 함수는 여러 객체의 속성을 복사해서 하나로 합칠 수 있습니다.

예를 들어, 다음 코드에서 target에 source의 속성을 복사한 returnedTarget은 target과 같은 속성들을 가집니다

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);		 // { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // { a: 1, b: 4, c: 5 }

이를 활용해 target 대신 빈 객체 {} 를 넣고 여러 개의 source 객체를 인자로 넣으면, 빈 객체에 다른 객체들이 합쳐진 새로운 객체를 얻을 수 있습니다.

이는 연결형 상속 이라고도 하는데, 객체 속성을 복사함으로서 상속을 구현할 수 있습니다.
다음의 엔지니어를 만드는 예시를 보면 더 이해하기 쉽습니다.

const jsSkill = {
  knowJS() {
    return true
  }
}

const javaSkill = {
  knowJava() {
    return true
  }
}

const isWorking = {
  isWorking() {
    return true
  }
}

const frontendEngineer = Object.assign({}, jsSkill, isWorking)
const backendEngineer = Object.assign({}, javaSkill, isWorking)
const fullStackEngineer = Object.assign({}, jsSkill, javaSkill, isWorking)
profile
안녕하세요 프론트엔드 엔지니어 김예은입니다.

0개의 댓글