generated from muhandojeon/study-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6b09fc5
commit 5f5968c
Showing
1 changed file
with
182 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
# 자바스크립트 디자인 패턴 | ||
|
||
## 생성자 패턴 | ||
|
||
생성자는 객체가 새로 만들어진 뒤 초기화하는 데에 사용되는 특별한 메서드 | ||
|
||
### 객체 생성 | ||
|
||
```javascript | ||
const newObject = {}; | ||
const newObject = new Object(); | ||
``` | ||
|
||
> 자바스크립트 처음 배울 때 {} 이것보다 new Object()를 썼던 것 같아요. new Object()를 쓰면 이것이 객체라도 더 명확하게 말해줄 수 있지 않나? 싶었던... | ||
### 모듈 패턴 | ||
|
||
서로 다른 모듈 간의 클래스 또는 함수명 충돌을 방지할 수 있다. | ||
|
||
```html | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Document</title> | ||
</head> | ||
<body> | ||
<script> | ||
const newObject = {}; | ||
</script> | ||
<script> | ||
const newObject = new Object(); | ||
</script> | ||
</body> | ||
</html> | ||
``` | ||
|
||
newObject 변수가 충돌됨. | ||
|
||
### 싱글톤 패턴 | ||
|
||
> ex. 한 나라에는 한 번에 하나의 대통령만 존재할 수 있다. 업무를 할 때마다 동일한 대통령이 행동에 나서야 한다. 여기에서 대통령은 싱글톤이다. | ||
클래스의 인스턴스가 오직 하나만 존재하도록 제한하는 패턴 | ||
|
||
```javacript | ||
class President { | ||
private static instance: President; | ||
private constructor() { | ||
// 생성자 숨기기 | ||
} | ||
public static getInstance(): President { | ||
if (!President.instance) { | ||
President.instance = new President(); | ||
} | ||
return President.instance; | ||
} | ||
private clone(): void { | ||
// 복제 비활성화 | ||
} | ||
private wakeup(): void { | ||
// 데이터 역직렬화(unserialize) 비활성화 | ||
} | ||
} | ||
const president1: President = President.getInstance(); | ||
const president2: President = President.getInstance(); | ||
console.log(president1 === president2); // true | ||
``` | ||
|
||
> 책에서는 싱글톤을 사용하지 말라고 하는 것 같네요. | ||
> 종종 authorized axios instance, unauthorized axios instance 등등 싱글톤으로 몇 가지 인스턴스를 만들고 주구장창 가져다 쓰곤 했는데요, 이 방식에 대해 어떻게 생각하시나요? 그냥 axios 쓰는 것과, createInstance로 인스턴스를 만들어서 그걸 가져다 쓰는 방식 중에서 다들 어떻게 하고 계신지..! | ||
### 프로토타입 패턴 | ||
|
||
> ex. 복제된 양! 돌리(dolly) | ||
생성할 객체의 유형이 원형 인스턴스에 의해 결정되며, 이를 복제하여 새로운 객체를 생성한다. | ||
|
||
```javascript | ||
class Sheep { | ||
protected name: string; | ||
protected category: string; | ||
|
||
constructor(name: string, category: string = 'Mountain Sheep') { | ||
this.name = name; | ||
this.category = category; | ||
} | ||
|
||
setName(name: string): void { | ||
this.name = name; | ||
} | ||
|
||
getName(): string { | ||
return this.name; | ||
} | ||
|
||
setCategory(category: string): void { | ||
this.category = category; | ||
} | ||
|
||
getCategory(): string { | ||
return this.category; | ||
} | ||
|
||
const original: Sheep = new Sheep('Jolly'); | ||
console.log(original.getName()); // Jolly | ||
console.log(original.getCategory()); // Mountain Sheep | ||
|
||
const cloned: Sheep = Object.create(original); | ||
cloned.setName('Dolly'); | ||
console.log(cloned.getName()); // Dolly | ||
console.log(cloned.getCategory()); // Mountain Sheep | ||
``` | ||
프로토타입 패턴은 상속을 구현하는 쉬운 방법일 뿐만 아니라 성능에서의 이점도 챙길 수 있다. 객체 내의 함수를 정의할 때 복사본이 아닌 참조로 생성되어 모든 자식 객체가 동일한 함수를 가리키게 할 수 있기 때문이다. | ||
기존 객체와 유사한 객체가 필요하거나 복제에 비해 생성 비용이 많이 드는 경우에 사용한다. | ||
### 팩토리 패턴 | ||
> ex. 인사 담당자의 경우, 각 포지션에 대해 한 사람이 모든 면접을 진행하는 것은 불가능하다. 채용 공고에 따라 면접 절차를 결정하고 다른 사람들에게 위임해야 한다. | ||
```javascript | ||
abstract class HiringManager { | ||
// Factory method | ||
protected abstract makeInterviewer(): Interviewer; | ||
|
||
public takeInterview() { | ||
const interviewer = this.makeInterviewer(); | ||
interviewer.askQuestions(); | ||
} | ||
} | ||
|
||
interface Interviewer { | ||
askQuestions(): void; | ||
} | ||
|
||
class Developer implements Interviewer { | ||
askQuestions() { | ||
console.log('Asking about design patterns!'); | ||
} | ||
} | ||
|
||
class CommunityExecutive implements Interviewer { | ||
askQuestions() { | ||
console.log('Asking about community building'); | ||
} | ||
} | ||
|
||
class DevelopmentManager extends HiringManager { | ||
protected makeInterviewer(): Interviewer { | ||
return new Developer(); | ||
} | ||
} | ||
|
||
class MarketingManager extends HiringManager { | ||
protected makeInterviewer(): Interviewer { | ||
return new CommunityExecutive(); | ||
} | ||
} | ||
|
||
const devManager = new DevelopmentManager(); | ||
devManager.takeInterview(); // 출력: Asking about design patterns! | ||
|
||
const marketingManager = new MarketingManager(); | ||
marketingManager.takeInterview(); // 출력: Asking about community building. | ||
``` | ||
클래스에 일부 일반적인 처리가 있지만 필수 자식 클래스가 런타임에 동적으로 결정될 때 유용하다. 다른 말로 하면, 클라이언트가 정확히 어떤 자식 클래스가 필요한지 모를 때 사용된다. | ||
## 참고 | ||
- [(번역) 우리들을 위한 디자인 패턴](https://soobing.github.io/cs/design-patterns-for-humans/) |