diff --git "a/\354\261\225\355\204\260_7/\354\232\260\354\260\275\354\231\204.md" "b/\354\261\225\355\204\260_7/\354\232\260\354\260\275\354\231\204.md" new file mode 100644 index 0000000..2befe77 --- /dev/null +++ "b/\354\261\225\355\204\260_7/\354\232\260\354\260\275\354\231\204.md" @@ -0,0 +1,222 @@ +# 7. 자바스크립트 디자인패턴 (1/3) + + + +### 생성패턴 + +* 생성자 패턴 +* 모듈 패턴 +* 노출 모듈 패턴 +* 싱글톤 패턴 +* 프로토타입 패턴 +* 팩토리 패턴 + + + +### 7.2 생성자 패턴 + + + +#### 7.2.1 객체 생성 + +```js +// <= es5 + +const newObject = {} + +Object.defineProperty(newObject, "name", { + value: "Foo", + writable: true, + enumerable: true, + configurable: true +}) + +//이렇게도 할당 가능 +newObject.name = "Bar" +console.log(newObject) +``` + + + +#### 7.2.2 생성자의 기본 특징 + +es6에서 도입된 class를 통해 객체를 생성하고 초기화할 수 있다. + +```js +class Person { + constructor(name) { + this.name = name + } +} + +const bun = new Person("FooBar") +console.log(bun) +``` + + + +### 7.3 모듈 패턴 + +모듈 패턴을 잘 알지 못하고 처음보았지만, es module을 native하게 지원하고 사용할 수 있는 환경에서 유용성이 큰가? 에 대해아직 물음표인 것 같다. + +es module은 그 자체로 모듈로서 동작하는데, 왜 모듈 래퍼를 하나 더 씌우는 건지 궁금하다. + + + +모듈 그 자체로의 장점은 단일 인스턴스를 보장한다는 점인 것 같다. 객체를 만들려면 singleton으로 몸 비틀기를 해야하는 Java에 비해 단일 인스턴스가 필요한 상황이면 모듈을 이용하는 것으로 충분해 보인다. + + + + + +### 7.3.4 WeakMap을 사용하는 최신 모듈 패턴 + +WeakMap을 통한 접근제한 필요할 때가 있을 것 같지만, class의 instance로 관리하는 것과 유사해보인다. + +1. 먼저, 모듈 변수를 이용한 패턴을 살펴보면, 두 가지 문제점을 볼 수 있다. (WeakMap ❌) + +* 모듈 내의 변수를 공유하게 된다. 즉, 인스턴스 간의 독립적인 상태를 갖지 못한다. +* 동일 모듈에서 모듈 변수들에게 자유롭게 접근이 가능하다. + +```js +let counter = 0; +let action; + +class Countdown { + constructor(initialCounter, initialAction) { + counter = initialCounter; // 모듈 스코프의 counter 변경 + action = initialAction; // 모듈 스코프의 action 변경 + } + + dec() { + if (counter < 1) return; + + counter--; // 모듈 스코프의 counter 감소 + + if (counter === 0) { + action(); // 모듈 스코프의 action 호출 + } + } +} +``` + + + +2. 클래스 내의 멤버 변수로 선언할 경우. + +* 자바스크립트는 비공개 필드를 선언할 수 없었다. + +```js +class Countdown { + counter; + action; + + constructor(counter, action) { + this.counter = counter; + this.action = action; + } + + dec() { + if (this.counter < 1) return; + + this.counter--; // 프라이빗 필드 값 감소 + + if (this.counter === 0) { + this.action(); // 프라이빗 필드로 접근 + } + } +} +const c = new Countdown(2, () => console.log('DONE')); +console.log(c.counter); //2 +c.counter = -1; +console.log(c.counter); // -1 +``` + + + +es2019에 추가된 private class member(`#`)가 도입되었다. 사실 private class member는 트랜스파일링 시, weakMap으로 트랜스파일링 된다. + +```js +class A { + #privateFieldA = 1; +} + +// 트랜스파일링 +var _privateFieldA = /*#__PURE__*/new WeakMap(); + +class A { + constructor() { + _privateFieldA.set(this, { + writable: true, + value: 1 + }); + } +} + +``` + + + + + +#### 7.4 노출 모듈 패턴 + +export로 비공개/공개 요소를 지정하는 것보다 포인터 객체를 만드는 것이 어떤 이점이 있는지 잘 모르겠다.. + + + +#### 7.5 싱글톤 패턴 + +Java의 싱글톤 패턴을 자바스크립트에서 사용하면 문제가 있는지 의심해봐야한다. + + + +#### 7.7 팩토리 패턴 + +싱글 팩토리 패턴 + +```js +function createVechicle(data) { + switch(data.type) { + case "car": + return new Car({...}); + case "truck": + return new Truck({...}); + default: + throw new Error("일체하는 type이 없습니다.") + } +} +``` + + + +위의 싱글 팩토리 패턴은 srp, ocp 위반이다. 그래서 나온 것이 추상 팩토리 메서드 패턴이다. + +잘 동의가 안 되는게, 추상 팩토리를 만든다고 하더라도 진입점에서는 결국 분기처리 해주어야 하는 것이 아닌가? 결국 if,else 분기문의 위치만 달라진다고 느껴진다. + +그러면, 인터페이스 복잡도, 추상도만 올라가는 것 같은데.. 어떤 이점이 있는지 잘 모르겠다. 유용함을 깨달으면 수정해놓겠지. + + + + + + + + + + + + + + + + + + + + + + + + +