From 63580d8bef057c3cb28af1f24fad6723c74fbf30 Mon Sep 17 00:00:00 2001 From: SangBeom Park Date: Sun, 3 Nov 2024 19:07:52 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\203\201\353\262\224.md" | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 "\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" diff --git "a/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" new file mode 100644 index 0000000..f7fd4f9 --- /dev/null +++ "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" @@ -0,0 +1,88 @@ +## 구조 패턴 +구조 패턴은 클래스와 객체의 구성을 다룬다 +- 퍼사드 패턴 +- 믹스인 패턴 +- 데코레이터 패턴 +- 플라이웨이트 패턴 + +## 퍼사드 패턴 +> 퍼사드는 건물의 외관을 뜻함 + +퍼사드 패턴은 심층적인 복잡성을 숨기고, 사용하기 편리한 높은 수준의 인터페이스를 제공하는 패턴 + +퍼사드는 jQuery에서 흔히 볼 수 있는 구조 패턴 + +장점 : 사용하기 쉽다, 패턴 구현에 필요한 코드 양이 적다 +단점은 안적혀 있음 ㄷ ㄷ + +> 복잡한 내부를 감추고 사용자에게 단순한 인터페이스를 제공한다는 점에서 선언적 프로그래밍 기조와 비슷하다고 느낌 + + +## 믹스인 패턴 +믹스인은 서브클래스가 쉽게 상속받아 기능을 재사용할 수 있도록 하는 클래스 + +> [!NOTE] +> 서브클래스: 부모 클래스를 확장하는 자식 클래스 +> 서브클래싱: 부모 클래스 객체에서 상속받아 새로운 객체 만드는 것 + + +자바스크립트에서 클래스는 표현식 뿐만 아니라 문(statement) 으로도 사용할 수 있음 +평가될 때마다 새로운 클래스 반환함 + +```js +const MyMixins = superclass => + class extends superclass { + moveup() { + ... +``` + +> react에서도 관성적으로 사용해왔던게 기억남. 이것도 문으로 사용한 예시 맞나요..? +> ```js +> const componentMap = { +> A: ComponentA, +> B: ComponentB, +> }; +> const SelectedComponent = componentMap[componentType]; +> return +> ``` + +### 믹스인 패턴의 장단점 +장점: 함수의 중복을 줄이고 재사용성을 높인다 + - 기능을 공유하여 중복을 피하고 고유 기능을 구현하는데 집중 가능 + +단점: 프로토타입 오염과 함수의 출처에 대한 불확실성 때문에 논쟁의 여지가 있긴하다 함 + +리액트에서도 es6 클래스 도입 이전에는 컴포넌트 기능 추가하기 위해 믹스인을 사용하곤 했는데, +컴포넌트의 유지보수와 재사용을 복잡하게 만든다는 이유로 반대하고 HOC나 hooks 사용을 장려했다고 하네요 + +## 데코레이터 패턴 +코드 재사용을 목표로 하는 구조 패턴 + +기본적으로 데코레이터는 기존 클래스에 동적으로 기능을 추가하기 위해 사용함 + +데코레이터 사용하면 기존 시스템의 내부 코드를 힘겹게 바꾸지 않고도 기능을 추가할 수 있게 됨 + +데코레이터 패턴을 사용하는 주된 이유는 애플리케이션의 기능이 다양한 타입의 객체를 필요로 할 수도 있기 때문이라고 함 + +예를 들어, hobbit, elf, orc 등 수백개의 생성자가 있고 캐릭터의 능력을 고려해 hobbitWithSword, hobbitWithWordAndRing 등등.. 조합에 따라 서브클래스를 엄청 만들어야 된다 + +객체의 생성을 신경 쓰지 않는 대신 기능의 확장에 좀 더 초점을 두는 것이다. + +이는 다시 말해, 서브 클래싱 대신 베이스 객체에 속성이나 메서드를 추가하여 간소화 하겠다는 아이디어다! + +장점: 유연하고 투명하게 사용될 수 있다! 베이스 객체가 변경될 걱정없이 사용 가능! +단점: 잘 관리하지 않으면 애플리케이션 구조를 무척 복잡하게 만들 수도 있다 => 이건 충분한 문서화나 패턴에 대한 이해도를 높임으로써 해결 가능하다고 함 + +## 플라이웨이트 패턴 +연관된 객체끼리 데이터를 공유하게 하면서 애플리케이션의 메모리를 최소화하는 패턴 + +> [!NOTE] +> 경량급처럼 패턴의 목표가 메모리 공간의 경량화 이기 때문에 복싱 체급인 플라이급에서 이름을 따왔다고 한다 + +플라이웨이트의 데이터 공유 방식은 여러 비슷한 객체나 데이터 구조에서 공통적으로 사용하는 부분만 하나의 외부 객체로 내보내는 것으로 이루어진다 한다 + +> 이벤트 위임도 플라이웨이트 패턴 적용한 예시라고 함 + +> 솔직히 책 내용이 와닿지는 않아서 다른 아티클 보고 공부했다 +> 플라이웨이트에 대해 잘 설명해주는 글 공유 하고 마무리 하겠습니다 +> https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-Flyweight-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90 From c0a313736d7dd580e6c0d10cfc39b8ae4fcc8910 Mon Sep 17 00:00:00 2001 From: SangBeom Park Date: Sun, 3 Nov 2024 19:13:14 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EA=B0=80=EB=8F=85=EC=84=B1=20=EC=A2=8B?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\203\201\353\262\224.md" | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git "a/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" index f7fd4f9..0f19d35 100644 --- "a/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" +++ "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" @@ -12,10 +12,12 @@ 퍼사드는 jQuery에서 흔히 볼 수 있는 구조 패턴 -장점 : 사용하기 쉽다, 패턴 구현에 필요한 코드 양이 적다 -단점은 안적혀 있음 ㄷ ㄷ +### 장점 +사용하기 쉽다, 패턴 구현에 필요한 코드 양이 적다 +### 단점 +은 안적혀 있음 ㄷ ㄷ -> 복잡한 내부를 감추고 사용자에게 단순한 인터페이스를 제공한다는 점에서 선언적 프로그래밍 기조와 비슷하다고 느낌 +> 퍼사드 패턴은 복잡한 내부를 감추고 사용자에게 단순한 인터페이스를 제공한다는 점에서 선언적 프로그래밍 기조와 비슷하다고 느낌 ## 믹스인 패턴 @@ -46,11 +48,13 @@ const MyMixins = superclass => > return > ``` -### 믹스인 패턴의 장단점 -장점: 함수의 중복을 줄이고 재사용성을 높인다 - - 기능을 공유하여 중복을 피하고 고유 기능을 구현하는데 집중 가능 +### 장점 +함수의 중복을 줄이고 재사용성을 높인다 +- 기능을 공유하여 중복을 피하고 고유 기능을 구현하는데 집중 가능 + +### 단점 +프로토타입 오염과 함수의 출처에 대한 불확실성 때문에 논쟁의 여지가 있긴하다 함 -단점: 프로토타입 오염과 함수의 출처에 대한 불확실성 때문에 논쟁의 여지가 있긴하다 함 리액트에서도 es6 클래스 도입 이전에는 컴포넌트 기능 추가하기 위해 믹스인을 사용하곤 했는데, 컴포넌트의 유지보수와 재사용을 복잡하게 만든다는 이유로 반대하고 HOC나 hooks 사용을 장려했다고 하네요 @@ -70,8 +74,12 @@ const MyMixins = superclass => 이는 다시 말해, 서브 클래싱 대신 베이스 객체에 속성이나 메서드를 추가하여 간소화 하겠다는 아이디어다! -장점: 유연하고 투명하게 사용될 수 있다! 베이스 객체가 변경될 걱정없이 사용 가능! -단점: 잘 관리하지 않으면 애플리케이션 구조를 무척 복잡하게 만들 수도 있다 => 이건 충분한 문서화나 패턴에 대한 이해도를 높임으로써 해결 가능하다고 함 +### 장점 +유연하고 투명하게 사용될 수 있다! 베이스 객체가 변경될 걱정없이 사용 가능! + +### 단점 +잘 관리하지 않으면 애플리케이션 구조를 무척 복잡하게 만들 수도 있다 +- 이건 충분한 문서화나 패턴에 대한 이해도를 높임으로써 해결 가능하다고 함 ## 플라이웨이트 패턴 연관된 객체끼리 데이터를 공유하게 하면서 애플리케이션의 메모리를 최소화하는 패턴 From 27dd4f07c290c317639908f039aecbdcb8b4ecef Mon Sep 17 00:00:00 2001 From: SangBeom Park Date: Mon, 4 Nov 2024 09:16:32 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=08=EC=B6=A9=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\203\201\353\262\224.md" | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git "a/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" index 0f19d35..e71209b 100644 --- "a/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" +++ "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" @@ -1,3 +1,149 @@ +# 챕터7 자바스크립트 디자인 패턴 + +## 7.1 생성 패턴 +- 생성자 패턴 +- 모듈 패턴 +- 노출 묘듈 패턴 +- 싱글톤 패턴 +- 프로토타입 패턴 +- 팩토리 패턴 + +## 7.2 생성자 패턴 +- es6 출시 이후로 생성자 가진 클래스 만들 수 있게 됨 +- 클래스는 자바스크립트가 가진 프로토타입의 상속을 이용한 문법적 설탕임 +- 새 객체를 초기화하는 constructor() 메서드를 갖고 있어야 됨. new 키워드는 생성자 호출하고 생성자 내부의 this는 새로 생성된 해당 객체 가리킴 + +```js +class Car { + constructor(...) { + ... + } + toString() { + } +} +``` + +생성자 기본 예제인데 여기서 몇가지 문제 있음 +- 상속 어려워짐 +- 생성자로 인스턴스 생성하면 같은 함수 새로 정의하게 됨 + +```js +class Car { + constructor(...) { + ... + } + Car.prototype.toString = function() { + } +} +``` + +이를 해결하기 위해 생성자의 프로토타입에 메서드 추가하면 됨. 그러면 공유함 + +## 7.3 모듈 패턴 +객체 리터럴 => 우리가 흔히 작성하는 방식 + +es10 이전엔 접근 제한자(#)가 없었어서 변수 비공개 개념이 존재하지 않았음 +=> 이걸 함수 스코프를 이용해 비공개 개념을 구현함. 선언된 모듈 내부에서만 변수, 메서드 사용 가능 +=> 근데 반환되는 객체에 포함된 변수, 메서드는 공개되잖아? +=> 반환된 객체에 포함된 변수를 비공개하려면 WeakMap() 사용하면 됨 + +> [예제 링크](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/WeakMap#%EB%B9%84%EA%B3%B5%EA%B0%9C_%EB%A9%A4%EB%B2%84_%ED%9D%89%EB%82%B4%EB%82%B4%EA%B8%B0) + +아래 처럼 모듈 내에서 변수를 내보내지 않고 비공개로 사용 가능 ㄷ ㄷ + +```js +let _counter = new WeakMap(); + +class Module { + constructor() { + // 비공개 카운터 변수 + _counter.set(this, 0); + } + incrementCounter() { + let counter = _counter.get(this); + counter++; + _counter.set(this, counter); + return _counter.get(this); + } + resetCounter() { + console.log(`counter value prior to reset: ${_counter.get(this)}`); + _counter.set(this, 0); + } +} + +const testModule = new Module(); +``` + +믹스인 가져오기 변형, 내보내기 변형.. 시간이 지나면서 각자의 입맛에 맞는 모듈 패턴의 변형들이 등장하기 시작함 + +### 장점 +- 초보 개발자들도 이해하기 쉬움 (중요!) +- 사용하기 쉽고 모듈 사이의 의존성 관리하고 전역 요소를 원하는 만큼만 넘겨주어 유지보수 용이하게 됨 +- 바깥으로 노출 안하면 모듈 내부에 비공개로 유지 + +### 단점 +- 필요한 오류를 고칠 때 복잡도를 높일 수가 있다 + +## 7.4 노출 모듈 패턴 +일만이 행님이 답답해서 만든 패턴 + +비공개 함수와 속성에 접근하는 공개 포인터를 만듦. +이렇게 하면 모듈 가장 아래에 위치한 공개 객체를 더 알아보기 쉬워서 가독성 좋음 + +> 회사에서도 커스텀 훅은 다 노출 모듈 패턴으로 작성함 + + +## 7.5 싱글톤 패턴 +클래스의 인스턴스가 오직 하나만 존재하도록 제한하는 패턴 + +주의할 점은 실근톤이 '객체'나 '클래스'가 아닌 '구조'라는 점. 클로저 변수 변수 자체가 클로저가 아니라 클로저 제공하는 함수 스코프가 클로저를 뜻하는 거처럼.. + +```js +constructor() { + if (this._instance == null) { + if ( isFoo() ) { + this._instance = new FooSingleton(); + } else { + this._instance = new BasicSingleton(); + } + } + return this._instance; +}; +``` + +싱글톤은 지연된 실행이 중요! + +싱글톤을 정적 인스턴스로 구현했다 하더라도, 필요할 때까지는 리소스나 메모리를 소모하지 않도록 지연 생성 될 수 있다고 함 + +리액트에선 싱글톤 대신 context API 나 리덕스 같은 전역 상태 관리 도구 이용하여 개발 함 + +## 7.6 프로토타입 패턴 +이미 존재하는 객체를 복제해 만든 템플릿을 기반으로 새 객체를 생성하는 패턴 + +자바스크립트만이 가진 고유의 방식으로 작업 가능함 + +프로토타입 패턴은 상속 구현하는 쉬운 방법이면서 성능상 이점도 챙기기 가능 +=> 객체 내에 함수를 정의할 때 복사본이 아니라 참조로 생성되어 모든 자식 객체가 동일한 함수 가리키게 할 수 있음 + +## 7.7 팩토리 패턴 + +### 사용하면 좋은 상황 +- 객체나 컴포넌트 생성의 복잡성을 가질 때 +- 다양한 객체를 생성해야 할 때 +- 같은 속성을 공유하는 작은 객체를 다룰 때 +- 덕타이핑 같은 api 규칙만 충족하면 되는 다른 객체 인스턴스와 객체를 구성할 때 + +### 사용하면 안되는 상황 +- 객체 생성 과정이 인터페이스 뒤에 추상화하기 때문에 생성과정이 복잡할 경우 사용하지 마라 + +## 추상 팩토리 패턴 + +같은 목표를 가진 각각 팩토리를 하나의 그룹으로 캡슐화하는 패턴 + +추상 팩토리는 자동차나 트럭같은 차량 타입만 정의, 구체적 팩토리는 차량의 공통 기능을 충족하는 클래스만 구현 + +--- + ## 구조 패턴 구조 패턴은 클래스와 객체의 구성을 다룬다 - 퍼사드 패턴 From cbec05ba19121b227fa097471ba4d46fa7a74bb8 Mon Sep 17 00:00:00 2001 From: SangBeom Park Date: Tue, 5 Nov 2024 22:34:03 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Update=20=EC=83=81=EB=B2=94.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" | 9 --------- 1 file changed, 9 deletions(-) diff --git "a/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" index dff9135..e98c203 100644 --- "a/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" +++ "b/\354\261\225\355\204\260_7/\354\203\201\353\262\224.md" @@ -184,15 +184,6 @@ const MyMixins = superclass => ... ``` -> react에서도 관성적으로 사용해왔던게 기억남. 이것도 문으로 사용한 예시 맞나요..? -> ```js -> const componentMap = { -> A: ComponentA, -> B: ComponentB, -> }; -> const SelectedComponent = componentMap[componentType]; -> return -> ``` ### 장점 함수의 중복을 줄이고 재사용성을 높인다