sbyeol3/articles

[번역] 자바스크립트 디자인 패턴 Part 1 : 팩토리 패턴

Opened this issue · 0 comments

원문 : JavaScript Design Patterns Part 1: The Factory Pattern을 읽고 번역한 글입니다.

최근 작업한 프로젝트의 규모가 커지면서, 더욱 유지보수하기가 용이하고 확장성이 좋은 자바스크립트 코드를 작성하기 위해 디자인 패턴에 대해 깊게 알아보는 시간을 가졌습니다. 디자인 패턴은 일반적인 문제들에 시간이나 테스트 솔루션을 적용하기 좋은 방법입니다. 그래서 우리는 빠르고 효율적으로 그 문제들을 해결할 수 있죠.

우리가 알아볼 대부분의 디자인 패턴은은 객체지향 프로그래밍을 기반으로 하고 있고 객체를 생성하며 수반되는 여러 복잡한 것들이나 로직을 추상화하면서 객체를 생성하기 위한 명확한 인터페이스를 제공하므로 소위 creational 패턴부터 시작하는 것이 좋습니다. 이 패턴은 팩토리 패턴이라고 부르며 자바스크립트에서 쉽게 객체를 생성하게끔 합니다.

다른 객체지향 프로그래밍이나 클래스 기반 언어로부터 비롯되었다고 하여 우리가 클래스나 인스턴스를 생성하는 코드를 짜야한다고 생각할 수도 있지만 사실 문법적 sugar에 불과하여 클래스 기반 언어처럼 보이게 할 뿐입니다.

우리가 할 것은 자바스크립트의 프로토타입 상속과 OLOO(Objects Linking to Other Objects, 공유되는 프로토타입을 기반으로 객체를 생성하기 위해 객체들을 연결하는 것을 의미)를 활용하는 것입니다. 프로토타입 자체는 자바스크립트 객체일뿐이고 클래스는 아닙니다. 자바스크립트에서 상속과 클래스 기반 상속과의 차이를 을 가장 잘 설명하는 글은 Eric Elliot의 아티클을 참고하세요.

그럼 이제 코드를 살펴봅시다.

이 글에 있는 모든 예제 코드와 코드를 실행하는 가이드는 GitHub에서 보실 수 있습니다.

이 아티클의 코드를 실행하기 위해 여러분은 Node를 설치하셔야 합니다. 만약 설치하지 않으셨다면 이 안내사항을 따르세요. GitHub 레포 readme에 코드 실행하는 방법을 찾으실 수 있습니다.

먼저 폴더를 생성하세요. 이 폴더를 javascript-design-patters라 하고, 이 안에 factory 폴더를 생성합니다.

팩토리 패턴 동작

팩토리 패턴은 객체의 여러 타입으로 생성자를 감싸고 간단한 API를 통해 객체의 인스턴스를 반환합니다. 이는 구체화된 객체 타입을 리턴하는 간단한 API를 노출하여 여러 객체를 생성하는 것을 쉽게 만들어줍니다.

생성자를 생성해보는 것부터 시작합시다. 이 함수들은 호출되었을 때 특정 타입의 새로운 객체를 반환하는 역할을 합니다.
factory 폴더에서 laptop.js 파일을 생성합니다.

const Laptop = function({ ram, hdd, name }) {
  this.ram = ram || 0;
  this.hdd = hdd || 0;
  this.name = name || "";
};

module.exports = Laptop;

이 파일에서 Laptop 생성자 함수를 생성합니다. 객체를 파라미터로 받아 각 객체의 인스턴스의 어트리뷰트의 값으로 각 프로퍼티를 넣어줍니다. 이 경우에서는 RAM 사이즈, HDD 사이즈, 디바이스 이름을 사용하죠. 그 후 Laptop 생성자 함수를 모듈로부터 export합니다.

또 다른 파일인 tablet.js를 생성해봅시다. 비슷하지만 좀 더 태블릿에 관련된 것들을 추가해봅시다.

const Tablet = function({ ram, hdd, name, network }) {
    this.ram = ram || 0;
    this.hdd = hdd || 0;
    this.network = network || 0;
    this.name = name || "";
};

module.exports = Tablet;

생성자를 만들었으니 이런 아이템들을 가지는 새로운 인스턴스를 생성하는 API를 노출할 팩토리 함수를 생성해보겠습니다. gadgetFactory.js 파일을 추가해주세요.

const Laptop = require("./laptop");
const Tablet = require("./tablet");
const gadget = { Laptop, Tablet };
module.exports = {
    createGadget(type, attributes) {
        const GadgetType = gadget[type];
        return new GadgetType(attributes);
    }
};

LaptopTablet 객체들을 생성하는 생성자를 import 한 후 생성자 이름을 key로 사용하는 gadget 객체를 생성합니다. 이 예제에서는 gadget[type]을 사용하여 원하는 생성자의 타입에 접근할 수 있습니다. 타입은 "Laptop"이거나 "Tablet"입니다. 마지막으로 createGadget 메소드를 포함한 객체를 export합니다. 이 메소드는 첫 파라미터로 gadget type을 받고 어트리뷰트 값들을 해당 생성자에 넘겨주면서 호출합니다.

자바스크립트에서 new 키워드로 함수를 호출할 때 실행하는 함수에 this 바인딩이 된 빈 객체를 반환받는 것에 주목하셔야 합니다. 이 독특함은 생성자 함수와 이 방식으로 생성한 새 객체 사이의 프로토타입 관계를 만듭니다. 더 자세한 것은 나중에 다룰 디자인 패턴에서 살펴보겠습니다. 또 다른 주목할 점은 대문자로 시작하는 것은 관습이지 필수가 아니라는 것입니다. 대문자로 시작하는것은 어떤 특별한 기능도 하지 않습니다. 자바스크립트에서는 함수 이름이나 변수 이름에서 보통 사용하듯이 camelCase를 사용할 수도 있습니다.

이제 팩토리 패턴 API를 사용하는 파일을 생성할 수 있습니다. index.js 파일을 생성하고 아래 코드를 추가해주세요.

const gadgetFactory = require("./gadgetFactory");

const myLaptop = gadgetFactory.createGadget("Laptop", {
    ram: 8,
    ssd: 256,
    name: "Bab's MacBook Pro"
});

const myTablet = gadgetFactory.createGadget("Tablet", {
    ram: 4,
    hdd: 128,
    name: "Bab's iPad",
    network: '4G'
});

console.log(myLaptop);
console.log(myTablet);

아마 여러분은 첫 번째로 laptop이나 tablet 생성자가 직접적으로 필요하지 않다는 것을 보셨을 겁니다. 우리가 필요한 것은 gadgetFactory 모듈입니다. 이 메소드를 사용해서 두 가지 인스턴스를 생성하고 콘솔에 출력했습니다.

이제 여러분의 터미널에서 아까 생성한 javascript-design-patterns 폴더를 찾아 타이핑하세요.

$ node ./factory/index.js

콘솔에는 이렇게 출력됐을 겁니다.

Laptop { ram: 8, ssd: 256, name: 'Bab\'s MacBook Pro' }
Tablet { ram: 4, hdd: 128, network: '4G', name: 'Bab\'s iPad' }

여러분이 볼 수 있듯이 Laptop 객체 타입과 Tablet 객체 타입 모두를 생성했습니다. 이 패턴을 사용하여 여러분은 필요한 명세에 따라 많은 gadget 객체를 생성할 수 있습니다. 또한 이것이 팩토리 패턴입니다. 물론 훨씬 간단한 구현이고 여러분이 사용하려면 생성자 등에 더욱 엄격한 논리가 추가되어야 할 것입니다. 이 예시에서는 자바스크립트 생성자 함수를 사용했지만 프로토타입으로도 구현이 가능합니다. 이후 작성할 글에서는 코드를 더욱 효율적으로 리팩토링해보겠습니다.

다음 아티클 주제는 유명한 Publisher/Subscriber pattern에 대해 다뤄보겠습니다. 알림을 받고 싶으시면 저를 팔로우하시고, 만약 이 글이 도움이 되셨다면 thumbs up을 남겨주세요. 언제나 그랬듯이 아래 코멘트에서 여러분들의 생각을 들어보고 싶습니다.

업데이트 : 이 시리즈의 Part 2에서는 Publisher/Subscriber pattern에 대해 다룹니다.