Skip to content

Commit f3f757a

Browse files
authored
[이상조] 챕터 11: 네임스페이스 패턴 (#90)
1 parent 3aaf225 commit f3f757a

File tree

1 file changed

+348
-0
lines changed

1 file changed

+348
-0
lines changed

챕터_11/이상조.md

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
안녕하세요! 자바스크립트의 네임스페이스 패턴에 대해 설명해드리겠습니다.
2+
3+
## 네임스페이스란?
4+
5+
네임스페이스는 큰 프로그램을 구조화하고 관련 코드들을 논리적으로 그룹화하는 방법입니다. 주요 목적은 다음과 같습니다:
6+
7+
1. **이름 충돌 방지**: 서로 다른 부분의 코드에서 같은 이름을 사용할 때 발생할 수 있는 충돌을 방지
8+
2. **코드 구조화**: 관련된 기능들을 하나의 이름 아래 구조적으로 관리
9+
3. **전역 스코프 오염 방지**: 전역 변수/함수의 수를 줄여 전역 스코프의 오염을 방지
10+
11+
## 네임스페이스의 장점
12+
13+
1. **모듈화**: 코드를 논리적인 단위로 구분하여 관리 가능
14+
2. **캡슐화**: private 변수/함수를 구현할 수 있음
15+
3. **유지보수성**: 코드의 구조화로 인한 유지보수 용이성 향상
16+
4. **재사용성**: 필요한 기능만 선택적으로 사용 가능
17+
18+
## 네임스페이스의 단점
19+
20+
1. **깊은 중첩**: 네임스페이스가 깊어질수록 코드가 복잡해질 수 있음
21+
2. **성능**: 깊은 중첩의 경우 속성 접근 시간이 늘어날 수 있음
22+
3. **번들 크기**: 모든 코드가 하나의 객체에 포함되므로 불필요한 코드도 포함될 수 있음
23+
24+
25+
## 1. 단일 전역 변수 패턴
26+
27+
가장 기본적인 네임스페이스 패턴으로, 하나의 전역 객체를 생성하여 모든 기능을 이 객체에 추가하는 방식입니다.
28+
29+
```javascript
30+
var MYAPP = {};
31+
32+
MYAPP.name = "My Application";
33+
MYAPP.version = "1.0.0";
34+
35+
MYAPP.calculateTax = function(amount) {
36+
return amount * 0.1;
37+
};
38+
39+
MYAPP.formatCurrency = function(amount) {
40+
return `${amount.toLocaleString()}`;
41+
};
42+
```
43+
44+
### 장점:
45+
- 구현이 매우 간단함
46+
- 전역 네임스페이스 오염을 최소화
47+
- 코드 충돌 가능성 감소
48+
49+
### 단점:
50+
- 모든 변수와 함수가 public
51+
- 구조화가 부족
52+
- 확장성이 제한적
53+
54+
## 2. 접두사 네임스페이스 패턴
55+
56+
모든 변수와 함수 이름 앞에 특정 접두사를 붙여서 구분하는 방식입니다.
57+
58+
```javascript
59+
// 회사_프로젝트_기능 형태로 접두사 사용
60+
const COMPANY_PROJECT_userCount = 0;
61+
const COMPANY_PROJECT_maxUsers = 100;
62+
63+
function COMPANY_PROJECT_addUser() {
64+
if (COMPANY_PROJECT_userCount < COMPANY_PROJECT_maxUsers) {
65+
COMPANY_PROJECT_userCount++;
66+
}
67+
}
68+
69+
function COMPANY_PROJECT_removeUser() {
70+
if (COMPANY_PROJECT_userCount > 0) {
71+
COMPANY_PROJECT_userCount--;
72+
}
73+
}
74+
```
75+
76+
### 장점:
77+
- 구현이 매우 간단함
78+
- 이름 충돌 방지가 확실함
79+
80+
### 단점:
81+
- 코드가 지저분해짐
82+
- 타이핑해야 할 양이 많아짐
83+
- 압축이 어려움
84+
- 현대적인 개발에서는 거의 사용되지 않음
85+
86+
## 3. 객체 리터럴 표기법
87+
88+
관련된 기능들을 객체로 그룹화하는 패턴입니다.
89+
90+
```javascript
91+
const MyApplication = {
92+
// 설정 관련
93+
config: {
94+
apiUrl: 'https://api.example.com',
95+
timeout: 5000,
96+
debug: true
97+
},
98+
99+
// 유틸리티 함수들
100+
utils: {
101+
formatDate: function(date) {
102+
return new Date(date).toLocaleDateString();
103+
},
104+
validateEmail: function(email) {
105+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
106+
}
107+
},
108+
109+
// 사용자 관련 기능
110+
user: {
111+
data: {
112+
name: '',
113+
email: '',
114+
preferences: {}
115+
},
116+
login: function(credentials) {
117+
// 로그인 로직
118+
},
119+
logout: function() {
120+
// 로그아웃 로직
121+
},
122+
updatePreferences: function(newPrefs) {
123+
this.data.preferences = {...this.data.preferences, ...newPrefs};
124+
}
125+
}
126+
};
127+
128+
// 사용 예시
129+
MyApplication.utils.formatDate(new Date());
130+
MyApplication.user.login({username: 'test', password: '1234'});
131+
```
132+
133+
### 장점:
134+
- 코드 구조화가 명확함
135+
- 관련 기능들을 논리적으로 그룹화
136+
- 구현이 간단함
137+
138+
### 단점:
139+
- 모든 멤버가 public
140+
- 의존성 관리가 어려움
141+
- 큰 애플리케이션의 경우 관리가 복잡해질 수 있음
142+
143+
## 4. 중첩 네임스페이스 패턴
144+
145+
객체를 계층적으로 구성하는 패턴입니다.
146+
147+
```javascript
148+
var MYAPP = MYAPP || {};
149+
150+
// 중첩된 네임스페이스 생성 함수
151+
MYAPP.createNS = function(namespace) {
152+
let parts = namespace.split('.');
153+
let parent = MYAPP;
154+
155+
if (parts[0] === 'MYAPP') {
156+
parts = parts.slice(1);
157+
}
158+
159+
for (let i = 0; i < parts.length; i++) {
160+
if (typeof parent[parts[i]] === 'undefined') {
161+
parent[parts[i]] = {};
162+
}
163+
parent = parent[parts[i]];
164+
}
165+
166+
return parent;
167+
};
168+
169+
// 네임스페이스 생성
170+
MYAPP.createNS('MYAPP.models');
171+
MYAPP.createNS('MYAPP.views');
172+
MYAPP.createNS('MYAPP.controllers');
173+
174+
// 기능 구현
175+
MYAPP.models.User = function(name) {
176+
this.name = name;
177+
};
178+
179+
MYAPP.controllers.UserController = {
180+
createUser: function(name) {
181+
return new MYAPP.models.User(name);
182+
}
183+
};
184+
185+
// 사용 예시
186+
const userController = MYAPP.controllers.UserController;
187+
const newUser = userController.createUser('John');
188+
```
189+
190+
### 장점:
191+
- 체계적인 코드 구조화
192+
- 깊은 계층 구조 표현 가능
193+
- 모듈화가 용이
194+
195+
### 단점:
196+
- 긴 체이닝으로 인한 성능 저하 가능성
197+
- 코드가 복잡해질 수 있음
198+
- 의존성 관리가 어려움
199+
200+
## 5. 즉시 실행 함수 표현식 (IIFE) 패턴
201+
202+
함수를 즉시 실행하여 private 스코프를 만드는 패턴입니다.
203+
204+
```javascript
205+
var MYAPP = (function() {
206+
// private 변수와 함수
207+
let privateVariable = 0;
208+
209+
function privateFunction() {
210+
return privateVariable;
211+
}
212+
213+
// public API
214+
return {
215+
// public 변수
216+
publicVariable: "I'm public",
217+
218+
// public 메서드
219+
incrementCounter: function() {
220+
privateVariable++;
221+
return privateVariable;
222+
},
223+
224+
getCounter: function() {
225+
return privateFunction();
226+
},
227+
228+
// 모듈 초기화
229+
init: function() {
230+
// 초기화 로직
231+
console.log('Module initialized');
232+
}
233+
};
234+
})();
235+
236+
// 의존성 주입을 지원하는 버전
237+
var MYAPP = (function($, window, document, undefined) {
238+
// jQuery, window, document 객체를 지역 변수로 사용 가능
239+
240+
return {
241+
init: function() {
242+
$(document).ready(function() {
243+
// DOM 조작 로직
244+
});
245+
}
246+
};
247+
})(jQuery, window, document);
248+
```
249+
250+
### 장점:
251+
- private 스코프 생성 가능
252+
- 의존성 주입 가능
253+
- 클로저를 통한 데이터 은닉
254+
- 모듈화가 용이
255+
256+
### 단점:
257+
- 디버깅이 어려울 수 있음
258+
- 과도한 사용 시 메모리 사용량 증가
259+
- 복잡한 의존성 관리가 필요
260+
261+
## 6. 네임스페이스 주입 패턴
262+
263+
의존성을 외부에서 주입받는 패턴입니다.
264+
265+
```javascript
266+
var MYAPP = MYAPP || {};
267+
268+
// 네임스페이스 주입을 받는 모듈
269+
(function(app) {
270+
// private 변수
271+
let counter = 0;
272+
273+
// 모듈 기능을 네임스페이스에 추가
274+
app.module = {
275+
increment: function() {
276+
return ++counter;
277+
},
278+
decrement: function() {
279+
return --counter;
280+
}
281+
};
282+
283+
// 의존성이 필요한 기능
284+
app.dependentModule = function(utils) {
285+
return {
286+
doSomething: function() {
287+
// utils의 기능 사용
288+
return utils.helperFunction();
289+
}
290+
};
291+
};
292+
293+
})(MYAPP);
294+
295+
// 다른 모듈에서 의존성 주입
296+
(function(app) {
297+
// utils 모듈 정의
298+
app.utils = {
299+
helperFunction: function() {
300+
return 'Helper function called';
301+
}
302+
};
303+
304+
// dependentModule에 utils 주입
305+
app.initializedModule = app.dependentModule(app.utils);
306+
307+
})(MYAPP);
308+
309+
// 사용 예시
310+
console.log(MYAPP.module.increment()); // 1
311+
console.log(MYAPP.initializedModule.doSomething()); // "Helper function called"
312+
```
313+
314+
### 장점:
315+
- 유연한 의존성 관리
316+
- 테스트가 용이
317+
- 모듈 간 결합도 감소
318+
- 코드 재사용성 향상
319+
320+
### 단점:
321+
- 구현이 복잡할 수 있음
322+
- 의존성 관리가 복잡해질 수 있음
323+
- 초기 설정이 번거로움
324+
325+
---
326+
327+
처음 네임스페이스 듣고 타입스크립트 namespace랑 헷갈림
328+
329+
```ts
330+
namespace User {
331+
export interface Response {
332+
name: string;
333+
}
334+
335+
export interface Request {
336+
...
337+
}
338+
}
339+
340+
namespace Product {
341+
export interface Response {
342+
id: number;
343+
title: string;
344+
price: number;
345+
}
346+
}
347+
348+
```

0 commit comments

Comments
 (0)