๊ฒฌ๊ณ ํ ๋น์ฆ๋์ค ๋ก์ง ์บก์ํ, ํฅ์๋ ์ฝ๋ ๊ตฌ์ฑ, ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ง๋ณด์์ฑ ๊ฐํ๋ฅผ ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋ ์๋น์ค ํจํด์ ํ์ํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋ ์๋น์ค ํจํด: ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋น์ฆ๋์ค ๋ก์ง ์บก์ํ
ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ, ํนํ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ๋ ๋น์ฆ๋์ค ๋ก์ง์ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์บก์ํํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ ๋๋ก ๊ตฌ์กฐํ๋์ง ์์ ์ฝ๋๋ ์ ์ง๋ณด์์ ์ด๋ ค์, ์ฌ์ฌ์ฉ์ฑ ๊ฐ์, ๋ณต์ก์ฑ ์ฆ๊ฐ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋ ๋ฐ ์๋น์ค ํจํด์ ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๊ณ , ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ฅผ ๊ฐ์ ํ๋ฉฐ, ๋ ์ ์ง๋ณด์ํ๊ธฐ ์ฝ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋๋ ์ฐ์ํ ํด๊ฒฐ์ฑ ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์์๋ ์ด๋ฌํ ํจํด๋ค์ ํ์ํ๊ณ , ์ค์ ์์ ๋ฅผ ์ ๊ณตํ๋ฉฐ, ๋ค์ํ ๊ธ๋ก๋ฒ ํ๊ฒฝ์์ ์ด๋ป๊ฒ ์ ์ฉ๋ ์ ์๋์ง ๋ณด์ฌ์ค๋๋ค.
๋น์ฆ๋์ค ๋ก์ง์ ์บก์ํํด์ผ ํ๋ ์ด์
๋น์ฆ๋์ค ๋ก์ง์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ๋ํ๋ ๊ท์น๊ณผ ํ๋ก์ธ์ค๋ฅผ ํฌํจํฉ๋๋ค. ์ด๋ ๋ฐ์ดํฐ๊ฐ ์ด๋ป๊ฒ ๋ณํ๋๊ณ , ๊ฒ์ฆ๋๋ฉฐ, ์ฒ๋ฆฌ๋๋์ง๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ์ด ๋ก์ง์ ์บก์ํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ์ฃผ์ ์ด์ ์ด ์์ต๋๋ค:
- ํฅ์๋ ์ฝ๋ ๊ตฌ์ฑ: ๋ชจ๋์ ๋ช ํํ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ๋ถ๋ถ์ ์ฐพ๊ณ , ์ดํดํ๊ณ , ์์ ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
- ์ฆ๊ฐ๋ ์ฌ์ฌ์ฉ์ฑ: ์ ์ ์๋ ๋ชจ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ์ด๋ ์ฌ์ง์ด ์์ ํ ๋ค๋ฅธ ํ๋ก์ ํธ์์๋ ์ฌ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ์ด๋ ์ฝ๋ ์ค๋ณต์ ์ค์ด๊ณ ์ผ๊ด์ฑ์ ์ด์งํฉ๋๋ค.
- ํฅ์๋ ์ ์ง๋ณด์์ฑ: ๋น์ฆ๋์ค ๋ก์ง์ ๋ณ๊ฒฝ ์ฌํญ์ ํน์ ๋ชจ๋ ๋ด์ ๊ฒฉ๋ฆฌํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ์ ์๋์น ์์ ๋ถ์์ฉ์ ์ผ์ผํฌ ์ํ์ ์ต์ํํ ์ ์์ต๋๋ค.
- ๋จ์ํ๋ ํ ์คํธ: ๋ชจ๋์ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ ์ ์์ด ๋น์ฆ๋์ค ๋ก์ง์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค. ์ด๋ ๋ค๋ฅธ ๊ตฌ์ฑ ์์ ๊ฐ์ ์ํธ ์์ฉ์ ์์ธกํ๊ธฐ ์ด๋ ค์ด ๋ณต์กํ ์์คํ ์์ ํนํ ์ค์ํฉ๋๋ค.
- ๋ณต์ก์ฑ ๊ฐ์: ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ ์๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ๋ชจ๋๋ก ๋ถํดํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ์์คํ ์ ์ ์ฒด์ ์ธ ๋ณต์ก์ฑ์ ์ค์ผ ์ ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋ ํจํด
์๋ฐ์คํฌ๋ฆฝํธ๋ ๋ชจ๋์ ๋ง๋๋ ์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๋ค์์ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์ ๊ทผ ๋ฐฉ์ ์ค ์ผ๋ถ์ ๋๋ค:
1. ์ฆ์ ์คํ ํจ์ ํํ์ (IIFE)
IIFE ํจํด์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋ชจ๋์ ๋ง๋๋ ๊ณ ์ ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ฆ์ ์คํ๋๋ ํจ์ ๋ด์ ์ฝ๋๋ฅผ ๋ํํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ด๋ ๋น๊ณต๊ฐ ์ค์ฝํ๋ฅผ ์์ฑํ์ฌ IIFE ๋ด์ ์ ์๋ ๋ณ์์ ํจ์๊ฐ ์ ์ญ ๋ค์์คํ์ด์ค๋ฅผ ์ค์ผ์ํค๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
(function() {
// ๋น๊ณต๊ฐ ๋ณ์ ๋ฐ ํจ์
var privateVariable = "This is private";
function privateFunction() {
console.log(privateVariable);
}
// ๊ณต๊ฐ API
window.myModule = {
publicMethod: function() {
privateFunction();
}
};
})();
์์: ์ ์ญ ํตํ ๋ณํ๊ธฐ ๋ชจ๋์ ์์ํด ๋ณด์ธ์. IIFE๋ฅผ ์ฌ์ฉํ์ฌ ํ์จ ๋ฐ์ดํฐ๋ฅผ ๋น๊ณต๊ฐ๋ก ์ ์งํ๊ณ ํ์ํ ๋ณํ ํจ์๋ง ๋ ธ์ถํ ์ ์์ต๋๋ค.
(function() {
var exchangeRates = {
USD: 1.0,
EUR: 0.85,
JPY: 110.0,
GBP: 0.75 // ์์ ํ์จ
};
function convert(amount, fromCurrency, toCurrency) {
if (!exchangeRates[fromCurrency] || !exchangeRates[toCurrency]) {
return "Invalid currency";
}
return amount * (exchangeRates[toCurrency] / exchangeRates[fromCurrency]);
}
window.currencyConverter = {
convert: convert
};
})();
// ์ฌ์ฉ๋ฒ:
var convertedAmount = currencyConverter.convert(100, "USD", "EUR");
console.log(convertedAmount); // ์ถ๋ ฅ: 85
์ฅ์ :
- ๊ตฌํํ๊ธฐ ๊ฐ๋จํจ
- ์ข์ ์บก์ํ๋ฅผ ์ ๊ณตํจ
๋จ์ :
- ์ ์ญ ์ค์ฝํ์ ์์กดํจ (๋ํผ๋ก ์ํ๋๊ธฐ๋ ํจ)
- ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์กด์ฑ์ ๊ด๋ฆฌํ๊ธฐ ๋ฒ๊ฑฐ๋ก์์ง ์ ์์
2. CommonJS
CommonJS๋ ์๋ Node.js์ ํจ๊ป ์๋ฒ ์ธก ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์ ์ํด ์ค๊ณ๋ ๋ชจ๋ ์์คํ
์
๋๋ค. require() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ๊ฐ์ ธ์ค๊ณ module.exports ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ๋ด๋ณด๋
๋๋ค.
์์: ์ฌ์ฉ์ ์ธ์ฆ์ ์ฒ๋ฆฌํ๋ ๋ชจ๋์ ์๊ฐํด ๋ณด์ธ์.
auth.js
// auth.js
function authenticateUser(username, password) {
// ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ค๋ฅธ ์์ค๋ฅผ ํตํด ์ฌ์ฉ์ ์๊ฒฉ ์ฆ๋ช
๊ฒ์ฆ
if (username === "testuser" && password === "password") {
return { success: true, message: "Authentication successful" };
} else {
return { success: false, message: "Invalid credentials" };
}
}
module.exports = {
authenticateUser: authenticateUser
};
app.js
// app.js
const auth = require('./auth');
const result = auth.authenticateUser("testuser", "password");
console.log(result);
์ฅ์ :
- ๋ช ํํ ์์กด์ฑ ๊ด๋ฆฌ
- Node.js ํ๊ฒฝ์์ ๋๋ฆฌ ์ฌ์ฉ๋จ
๋จ์ :
- ๋ธ๋ผ์ฐ์ ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์๋์ง ์์ (Webpack์ด๋ Browserify์ ๊ฐ์ ๋ฒ๋ค๋ฌ ํ์)
3. ๋น๋๊ธฐ ๋ชจ๋ ์ ์ (AMD)
AMD๋ ์ฃผ๋ก ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ๋ชจ๋์ ๋น๋๊ธฐ์ ์ผ๋ก ๋ก๋ํ๊ธฐ ์ํด ์ค๊ณ๋์์ต๋๋ค. define() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ์ ์ํ๊ณ ๊ทธ ์์กด์ฑ์ ์ง์ ํฉ๋๋ค.
์์: ๋ค๋ฅธ ๋ก์ผ์ผ์ ๋ฐ๋ผ ๋ ์ง ํ์์ ์ง์ ํ๋ ๋ชจ๋์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค.
// date-formatter.js
define(['moment'], function(moment) {
function formatDate(date, locale) {
return moment(date).locale(locale).format('LL');
}
return {
formatDate: formatDate
};
});
// main.js
require(['date-formatter'], function(dateFormatter) {
var formattedDate = dateFormatter.formatDate(new Date(), 'fr');
console.log(formattedDate);
});
์ฅ์ :
- ๋ชจ๋์ ๋น๋๊ธฐ ๋ก๋ฉ
- ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์ ์ ํฉํจ
๋จ์ :
- CommonJS๋ณด๋ค ๊ตฌ๋ฌธ์ด ๋ ๋ณต์กํจ
4. ECMAScript ๋ชจ๋ (ESM)
ESM์ ECMAScript 2015 (ES6)์์ ๋์
๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ค์ดํฐ๋ธ ๋ชจ๋ ์์คํ
์
๋๋ค. import์ export ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์กด์ฑ์ ๊ด๋ฆฌํฉ๋๋ค. ESM์ ์ ์ ๋ ์ธ๊ธฐ๋ฅผ ์ป๊ณ ์์ผ๋ฉฐ ํ๋ ๋ธ๋ผ์ฐ์ ์ Node.js์์ ์ง์๋ฉ๋๋ค.
์์: ์ํ์ ๊ณ์ฐ์ ์ํํ๋ ๋ชจ๋์ ์๊ฐํด ๋ณด์ธ์.
math.js
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
app.js
// app.js
import { add, subtract } from './math.js';
const sum = add(5, 3);
const difference = subtract(10, 2);
console.log(sum); // ์ถ๋ ฅ: 8
console.log(difference); // ์ถ๋ ฅ: 8
์ฅ์ :
- ๋ธ๋ผ์ฐ์ ์ Node.js์์ ๋ค์ดํฐ๋ธ ์ง์
- ์ ์ ๋ถ์ ๋ฐ ํธ๋ฆฌ ์์ดํน (์ฌ์ฉํ์ง ์๋ ์ฝ๋ ์ ๊ฑฐ)
- ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ๊ตฌ๋ฌธ
๋จ์ :
- ์ค๋๋ ๋ธ๋ผ์ฐ์ ์ ๊ฒฝ์ฐ ๋น๋ ํ๋ก์ธ์ค(์: Babel)๊ฐ ํ์ํฉ๋๋ค. ํ๋ ๋ธ๋ผ์ฐ์ ๋ค์ด ์ ์ ๋ ESM์ ๋ค์ดํฐ๋ธ๋ก ์ง์ํ๊ณ ์์ง๋ง, ๋ ๋์ ํธํ์ฑ์ ์ํด ํธ๋์คํ์ผํ๋ ๊ฒ์ด ์ฌ์ ํ ์ผ๋ฐ์ ์ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ์๋น์ค ํจํด
๋ชจ๋ ํจํด์ด ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋จ์๋ก ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ ๋ฐ๋ฉด, ์๋น์ค ํจํด์ ํน์ ๋น์ฆ๋์ค ๋ก์ง์ ์บก์ํํ๊ณ ํด๋น ๋ก์ง์ ์ ๊ทผํ๊ธฐ ์ํ ์ผ๊ด๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. ์๋น์ค๋ ๋ณธ์ง์ ์ผ๋ก ํน์ ์์ ๋๋ ๊ด๋ จ ์์ ์งํฉ์ ์ํํ๋ ๋ชจ๋์ ๋๋ค.
1. ๋จ์ ์๋น์ค
๋จ์ ์๋น์ค๋ ํน์ ์์ ์ ์ํํ๋ ํจ์๋ ๋ฉ์๋ ์งํฉ์ ๋ ธ์ถํ๋ ๋ชจ๋์ ๋๋ค. ๋น์ฆ๋์ค ๋ก์ง์ ์บก์ํํ๊ณ ๋ช ํํ API๋ฅผ ์ ๊ณตํ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ๋๋ค.
์์: ์ฌ์ฉ์ ํ๋กํ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ์๋น์ค์ ๋๋ค.
// user-profile-service.js
const userProfileService = {
getUserProfile: function(userId) {
// ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ API์์ ์ฌ์ฉ์ ํ๋กํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก์ง
return new Promise(resolve => {
setTimeout(() => {
resolve({ id: userId, name: "John Doe", email: "john.doe@example.com" });
}, 500);
});
},
updateUserProfile: function(userId, profileData) {
// ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ API์์ ์ฌ์ฉ์ ํ๋กํ ๋ฐ์ดํฐ๋ฅผ ์
๋ฐ์ดํธํ๋ ๋ก์ง
return new Promise(resolve => {
setTimeout(() => {
resolve({ success: true, message: "Profile updated successfully" });
}, 500);
});
}
};
export default userProfileService;
// ์ฌ์ฉ๋ฒ (๋ค๋ฅธ ๋ชจ๋์์):
import userProfileService from './user-profile-service.js';
userProfileService.getUserProfile(123)
.then(profile => console.log(profile));
์ฅ์ :
- ์ดํดํ๊ณ ๊ตฌํํ๊ธฐ ์ฌ์
- ๋ช ํํ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ฅผ ์ ๊ณตํจ
๋จ์ :
- ๊ท๋ชจ๊ฐ ํฐ ์๋น์ค์์๋ ์์กด์ฑ์ ๊ด๋ฆฌํ๊ธฐ ์ด๋ ค์์ง ์ ์์
- ๋ ๋ฐ์ ๋ ํจํด๋งํผ ์ ์ฐํ์ง ์์ ์ ์์
2. ํฉํ ๋ฆฌ ํจํด
ํฉํ ๋ฆฌ ํจํด์ ๊ตฌ์ฒด์ ์ธ ํด๋์ค๋ฅผ ์ง์ ํ์ง ์๊ณ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๋ค๋ฅธ ๊ตฌ์ฑ์ด๋ ์์กด์ฑ์ ๊ฐ์ง ์๋น์ค๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
์์: ๋ค๋ฅธ ๊ฒฐ์ ๊ฒ์ดํธ์จ์ด์ ์ํธ ์์ฉํ๋ ์๋น์ค์ ๋๋ค.
// payment-gateway-factory.js
function createPaymentGateway(gatewayType, config) {
switch (gatewayType) {
case 'stripe':
return new StripePaymentGateway(config);
case 'paypal':
return new PayPalPaymentGateway(config);
default:
throw new Error('Invalid payment gateway type');
}
}
class StripePaymentGateway {
constructor(config) {
this.config = config;
}
processPayment(amount, token) {
// Stripe API๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ์ ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ก์ง
console.log(`Processing ${amount} via Stripe with token ${token}`);
return { success: true, message: "Payment processed successfully via Stripe" };
}
}
class PayPalPaymentGateway {
constructor(config) {
this.config = config;
}
processPayment(amount, accountId) {
// PayPal API๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ์ ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ก์ง
console.log(`Processing ${amount} via PayPal with account ${accountId}`);
return { success: true, message: "Payment processed successfully via PayPal" };
}
}
export default {
createPaymentGateway: createPaymentGateway
};
// Usage:
import paymentGatewayFactory from './payment-gateway-factory.js';
const stripeGateway = paymentGatewayFactory.createPaymentGateway('stripe', { apiKey: 'YOUR_STRIPE_API_KEY' });
const paypalGateway = paymentGatewayFactory.createPaymentGateway('paypal', { clientId: 'YOUR_PAYPAL_CLIENT_ID' });
stripeGateway.processPayment(100, 'TOKEN123');
paypalGateway.processPayment(50, 'ACCOUNT456');
์ฅ์ :
- ๋ค๋ฅธ ์๋น์ค ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๋ฐ ์ ์ฐํจ
- ๊ฐ์ฒด ์์ฑ์ ๋ณต์ก์ฑ์ ์จ๊น
๋จ์ :
- ์ฝ๋์ ๋ณต์ก์ฑ์ ์ถ๊ฐํ ์ ์์
3. ์์กด์ฑ ์ฃผ์ (DI) ํจํด
์์กด์ฑ ์ฃผ์ ์ ์๋น์ค๊ฐ ์ง์ ์์กด์ฑ์ ์์ฑํ๋ ๋์ ์๋น์ค์ ์์กด์ฑ์ ์ ๊ณตํ ์ ์๊ฒ ํ๋ ๋์์ธ ํจํด์ ๋๋ค. ์ด๋ ๋์จํ ๊ฒฐํฉ์ ์ด์งํ๊ณ ์ฝ๋์ ํ ์คํธ ๋ฐ ์ ์ง๋ณด์๋ฅผ ๋ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
์์: ์ฝ์์ด๋ ํ์ผ์ ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํ๋ ์๋น์ค์ ๋๋ค.
// logger.js
class Logger {
constructor(output) {
this.output = output;
}
log(message) {
this.output.write(message + '\n');
}
}
// console-output.js
class ConsoleOutput {
write(message) {
console.log(message);
}
}
// file-output.js
const fs = require('fs');
class FileOutput {
constructor(filePath) {
this.filePath = filePath;
}
write(message) {
fs.appendFileSync(this.filePath, message + '\n');
}
}
// app.js
const Logger = require('./logger.js');
const ConsoleOutput = require('./console-output.js');
const FileOutput = require('./file-output.js');
const consoleOutput = new ConsoleOutput();
const fileOutput = new FileOutput('log.txt');
const consoleLogger = new Logger(consoleOutput);
const fileLogger = new Logger(fileOutput);
consoleLogger.log('This is a console log message');
fileLogger.log('This is a file log message');
์ฅ์ :
- ์๋น์ค์ ๊ทธ ์์กด์ฑ ๊ฐ์ ๋์จํ ๊ฒฐํฉ
- ํฅ์๋ ํ ์คํธ ์ฉ์ด์ฑ
- ์ฆ๊ฐ๋ ์ ์ฐ์ฑ
๋จ์ :
- ํนํ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํฌ ์ ์์ต๋๋ค. ์์กด์ฑ ์ฃผ์ ์ปจํ ์ด๋(์: InversifyJS)๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ๋ณต์ก์ฑ์ ๊ด๋ฆฌํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
4. ์ ์ด์ ์ญ์ (IoC) ์ปจํ ์ด๋
IoC ์ปจํ ์ด๋(DI ์ปจํ ์ด๋๋ผ๊ณ ๋ ํจ)๋ ์์กด์ฑ์ ์์ฑ๊ณผ ์ฃผ์ ์ ๊ด๋ฆฌํ๋ ํ๋ ์์ํฌ์ ๋๋ค. ์์กด์ฑ ์ฃผ์ ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํ๊ณ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์กด์ฑ์ ๊ตฌ์ฑํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค. ์ด๋ ๊ตฌ์ฑ ์์์ ๊ทธ ์์กด์ฑ์ ์ค์ ๋ ์ง์คํธ๋ฆฌ๋ฅผ ์ ๊ณตํ ๋ค์, ๊ตฌ์ฑ ์์๊ฐ ์์ฒญ๋ ๋ ํด๋น ์์กด์ฑ์ ์๋์ผ๋ก ํด๊ฒฐํ๋ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค.
InversifyJS๋ฅผ ์ฌ์ฉํ ์์:
// InversifyJS ์ค์น: npm install inversify reflect-metadata --save
// logger.ts
import { injectable } from "inversify";
export interface Logger {
log(message: string): void;
}
@injectable()
export class ConsoleLogger implements Logger {
log(message: string): void {
console.log(message);
}
}
// notification-service.ts
import { injectable, inject } from "inversify";
import { Logger } from "./logger";
import { TYPES } from "./types";
export interface NotificationService {
sendNotification(message: string): void;
}
@injectable()
export class EmailNotificationService implements NotificationService {
private logger: Logger;
constructor(@inject(TYPES.Logger) logger: Logger) {
this.logger = logger;
}
sendNotification(message: string): void {
this.logger.log(`Sending email notification: ${message}`);
// ์ด๋ฉ์ผ ๋ฐ์ก ์๋ฎฌ๋ ์ด์
console.log(`Email sent: ${message}`);
}
}
// types.ts
export const TYPES = {
Logger: Symbol.for("Logger"),
NotificationService: Symbol.for("NotificationService")
};
// container.ts
import { Container } from "inversify";
import { TYPES } from "./types";
import { Logger, ConsoleLogger } from "./logger";
import { NotificationService, EmailNotificationService } from "./notification-service";
import "reflect-metadata"; // InversifyJS์ ํ์
const container = new Container();
container.bind(TYPES.Logger).to(ConsoleLogger);
container.bind(TYPES.NotificationService).to(EmailNotificationService);
export { container };
// app.ts
import { container } from "./container";
import { TYPES } from "./types";
import { NotificationService } from "./notification-service";
const notificationService = container.get(TYPES.NotificationService);
notificationService.sendNotification("Hello from InversifyJS!");
์ค๋ช :
- `@injectable()`: ํด๋์ค๊ฐ ์ปจํ ์ด๋์ ์ํด ์ฃผ์ ๋ ์ ์์์ ํ์ํฉ๋๋ค.
- `@inject(TYPES.Logger)`: ์์ฑ์๊ฐ `Logger` ์ธํฐํ์ด์ค์ ์ธ์คํด์ค๋ฅผ ๋ฐ์์ผ ํจ์ ์ง์ ํฉ๋๋ค.
- `TYPES.Logger` & `TYPES.NotificationService`: ๋ฐ์ธ๋ฉ์ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ฌ๋ณผ์ ๋๋ค. ์ฌ๋ณผ์ ์ฌ์ฉํ๋ฉด ์ด๋ฆ ์ถฉ๋์ ํผํ ์ ์์ต๋๋ค.
- `container.bind
(TYPES.Logger).to(ConsoleLogger)`: ์ปจํ ์ด๋๊ฐ `Logger`๋ฅผ ํ์๋ก ํ ๋ `ConsoleLogger`์ ์ธ์คํด์ค๋ฅผ ์์ฑํด์ผ ํจ์ ๋ฑ๋กํฉ๋๋ค. - `container.get
(TYPES.NotificationService)`: `NotificationService`์ ๊ทธ ๋ชจ๋ ์์กด์ฑ์ ํด๊ฒฐํฉ๋๋ค.
์ฅ์ :
- ์ค์ ์ง์ค์ ์์กด์ฑ ๊ด๋ฆฌ
- ๋จ์ํ๋ ์์กด์ฑ ์ฃผ์
- ํฅ์๋ ํ ์คํธ ์ฉ์ด์ฑ
๋จ์ :
- ์ด๊ธฐ์ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ๋ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์๋ ์ถ์ํ ๊ณ์ธต์ ์ถ๊ฐํจ
- ์๋ก์ด ํ๋ ์์ํฌ ํ์ต์ด ํ์ํจ
๋ค์ํ ๊ธ๋ก๋ฒ ํ๊ฒฝ์์ ๋ชจ๋ ๋ฐ ์๋น์ค ํจํด ์ ์ฉํ๊ธฐ
๋ชจ๋ ๋ฐ ์๋น์ค ํจํด์ ์์น์ ๋ณดํธ์ ์ผ๋ก ์ ์ฉ ๊ฐ๋ฅํ์ง๋ง, ํน์ ์ง์ญ์ด๋ ๋น์ฆ๋์ค ํ๊ฒฝ์ ๋ง๊ฒ ๊ตฌํ์ ์กฐ์ ํด์ผ ํ ์๋ ์์ต๋๋ค. ๋ค์์ ๋ช ๊ฐ์ง ์์์ ๋๋ค:
- ํ์งํ: ๋ชจ๋์ ์ฌ์ฉํ์ฌ ๋ ์ง ํ์, ํตํ ๊ธฐํธ, ์ธ์ด ๋ฒ์ญ๊ณผ ๊ฐ์ ๋ก์ผ์ผ ํน์ ๋ฐ์ดํฐ๋ฅผ ์บก์ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ์๋น์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ์์น์ ๊ด๊ณ์์ด ์ด ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ธฐ ์ํ ์ผ๊ด๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ ์ง ํ์ ์ง์ ์๋น์ค๋ ๋ค๋ฅธ ๋ก์ผ์ผ์ ๋ํด ๋ค๋ฅธ ๋ชจ๋์ ์ฌ์ฉํ์ฌ ๊ฐ ์ง์ญ์ ๋ง๋ ์ฌ๋ฐ๋ฅธ ํ์์ผ๋ก ๋ ์ง๋ฅผ ํ์ํ๋๋ก ํ ์ ์์ต๋๋ค.
- ๊ฒฐ์ ์ฒ๋ฆฌ: ํฉํ ๋ฆฌ ํจํด์์ ๋ณด์ฌ์ค ๋ฐ์ ๊ฐ์ด, ์ง์ญ๋ง๋ค ๋ค๋ฅธ ๊ฒฐ์ ๊ฒ์ดํธ์จ์ด๊ฐ ์ผ๋ฐ์ ์ ๋๋ค. ์๋น์ค๋ ๋ค๋ฅธ ๊ฒฐ์ ์ ๊ณต์ ์ฒด์์ ์ํธ ์์ฉ์ ๋ณต์ก์ฑ์ ์ถ์ํํ์ฌ ๊ฐ๋ฐ์๊ฐ ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง์ ์ง์คํ ์ ์๋๋ก ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ ๋ฝ์ ์ ์์๊ฑฐ๋ ์ฌ์ดํธ๋ SEPA ์๋์ด์ฒด๋ฅผ ์ง์ํด์ผ ํ ์ ์๊ณ , ๋ถ๋ฏธ ์ฌ์ดํธ๋ Stripe๋ PayPal๊ณผ ๊ฐ์ ์ ๊ณต์ ์ฒด๋ฅผ ํตํ ์ ์ฉ์นด๋ ์ฒ๋ฆฌ์ ์ค์ ์ ๋ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๊ท์ : ๋ชจ๋์ ์ฌ์ฉํ์ฌ GDPR์ด๋ CCPA ์ค์์ ๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๋ก์ง์ ์บก์ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ์๋น์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ์์น์ ๊ด๊ณ์์ด ๊ด๋ จ ๊ท์ ์ ๋ฐ๋ผ ๋ฐ์ดํฐ๊ฐ ์ฒ๋ฆฌ๋๋๋ก ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์ ๋ฐ์ดํฐ ์๋น์ค๋ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ์ํธํํ๊ณ , ๋ถ์ ๋ชฉ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ต๋ช ํํ๋ฉฐ, ์ฌ์ฉ์์๊ฒ ์์ ์ ๋ฐ์ดํฐ์ ์ ๊ทผ, ์์ ๋๋ ์ญ์ ํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๋ชจ๋์ ํฌํจํ ์ ์์ต๋๋ค.
- API ํตํฉ: ์ง์ญ๋ณ ๊ฐ์ฉ์ฑ์ด๋ ๊ฐ๊ฒฉ์ด ๋ค๋ฅธ ์ธ๋ถ API์ ํตํฉํ ๋, ์๋น์ค ํจํด์ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ์ฐจ์ด์ ์ ์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋งคํ ์๋น์ค๋ Google ์ง๋๋ฅผ ์ฌ์ฉํ ์ ์๊ณ ์ ๋ ดํ ์ง์ญ์์๋ ์ด๋ฅผ ์ฌ์ฉํ๊ณ , ๋ค๋ฅธ ์ง์ญ์์๋ Mapbox์ ๊ฐ์ ๋์ฒด ์ ๊ณต์ ์ฒด๋ก ์ ํํ ์ ์์ต๋๋ค.
๋ชจ๋ ๋ฐ ์๋น์ค ํจํด ๊ตฌํ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
๋ชจ๋ ๋ฐ ์๋น์ค ํจํด์ ์ต๋ํ ํ์ฉํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ณ ๋ คํ์ญ์์ค:
- ๋ช ํํ ์ฑ ์ ์ ์: ๊ฐ ๋ชจ๋๊ณผ ์๋น์ค๋ ๋ช ํํ๊ณ ์ ์ ์๋ ๋ชฉ์ ์ ๊ฐ์ ธ์ผ ํฉ๋๋ค. ๋๋ฌด ํฌ๊ฑฐ๋ ๋ณต์กํ ๋ชจ๋์ ๋ง๋ค์ง ๋ง์ญ์์ค.
- ์ค๋ช ์ ์ธ ์ด๋ฆ ์ฌ์ฉ: ๋ชจ๋์ด๋ ์๋น์ค์ ๋ชฉ์ ์ ์ ํํ๊ฒ ๋ฐ์ํ๋ ์ด๋ฆ์ ์ ํํ์ญ์์ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ค๋ฅธ ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ดํดํ ์ ์์ต๋๋ค.
- ์ต์ํ์ API ๋ ธ์ถ: ์ธ๋ถ ์ฌ์ฉ์๊ฐ ๋ชจ๋์ด๋ ์๋น์ค์ ์ํธ ์์ฉํ๋ ๋ฐ ํ์ํ ํจ์์ ๋ฉ์๋๋ง ๋ ธ์ถํ์ญ์์ค. ๋ด๋ถ ๊ตฌํ ์ธ๋ถ ์ ๋ณด๋ ์จ๊ธฐ์ญ์์ค.
- ๋จ์ ํ ์คํธ ์์ฑ: ๊ฐ ๋ชจ๋๊ณผ ์๋น์ค์ ๋ํด ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํ์ฌ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ์ญ์์ค. ์ด๋ ํ๊ท๋ฅผ ๋ฐฉ์งํ๊ณ ์ฝ๋๋ฅผ ์ ์ง๋ณด์ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค. ๋์ ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ชฉํ๋ก ํ์ญ์์ค.
- ์ฝ๋ ๋ฌธ์ํ: ํจ์ ๋ฐ ๋ฉ์๋์ ๋ํ ์ค๋ช , ๋งค๊ฐ๋ณ์ ๋ฐ ๋ฐํ ๊ฐ์ ํฌํจํ์ฌ ๊ฐ ๋ชจ๋ ๋ฐ ์๋น์ค์ API๋ฅผ ๋ฌธ์ํํ์ญ์์ค. JSDoc๊ณผ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์๋ฅผ ์๋์ผ๋ก ์์ฑํ์ญ์์ค.
- ์ฑ๋ฅ ๊ณ ๋ ค: ๋ชจ๋๊ณผ ์๋น์ค๋ฅผ ์ค๊ณํ ๋ ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ ๊ณ ๋ คํ์ญ์์ค. ๋๋ฌด ๋ง์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋์ ๋ง๋ค์ง ๋ง์ญ์์ค. ์๋์ ํจ์จ์ฑ์ ์ํด ์ฝ๋๋ฅผ ์ต์ ํํ์ญ์์ค.
- ์ฝ๋ ๋ฆฐํฐ ์ฌ์ฉ: ์ฝ๋ ๋ฆฐํฐ(์: ESLint)๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋ฉ ํ์ค์ ๊ฐ์ ํ๊ณ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์๋ณํ์ญ์์ค. ์ด๋ ํ๋ก์ ํธ ์ ๋ฐ์ ๊ฑธ์ณ ์ฝ๋ ํ์ง๊ณผ ์ผ๊ด์ฑ์ ์ ์งํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
๊ฒฐ๋ก
์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋ ๋ฐ ์๋น์ค ํจํด์ ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๊ณ , ๋น์ฆ๋์ค ๋ก์ง์ ์บก์ํํ๋ฉฐ, ๋ ์ ์ง๋ณด์ํ๊ธฐ ์ฝ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ์ด๋ฌํ ํจํด์ ์ดํดํ๊ณ ์ ์ฉํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ์ดํดํ๊ณ , ํ ์คํธํ๊ณ , ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ฐ์ ์ํค๊ธฐ ์ฌ์ด ๊ฒฌ๊ณ ํ๊ณ ์ ๊ตฌ์กฐํ๋ ์์คํ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ํน์ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ํ๋ก์ ํธ์ ํ์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์ง๋ง, ๊ธฐ๋ณธ ์์น์ ๋์ผํฉ๋๋ค: ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํ๊ณ , ์์กด์ฑ์ ์ต์ํํ๋ฉฐ, ๋น์ฆ๋์ค ๋ก์ง์ ์ ๊ทผํ๊ธฐ ์ํ ๋ช ํํ๊ณ ์ผ๊ด๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ค.
์ด๋ฌํ ํจํด์ ์ฑํํ๋ ๊ฒ์ ๊ธ๋ก๋ฒ ๊ณ ๊ฐ์ ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ๋ ํนํ ์ค์ํฉ๋๋ค. ํ์งํ, ๊ฒฐ์ ์ฒ๋ฆฌ, ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๋ก์ง์ ์ ์ ์๋ ๋ชจ๋๊ณผ ์๋น์ค๋ก ์บก์ํํจ์ผ๋ก์จ ์ฌ์ฉ์์ ์์น๋ ๋ฌธํ์ ๋ฐฐ๊ฒฝ์ ๊ด๊ณ์์ด ์ ์ ๊ฐ๋ฅํ๊ณ ๊ท์ ์ ์ค์ํ๋ฉฐ ์ฌ์ฉ์ ์นํ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์์ต๋๋ค.