๊ฒฌ๊ณ ํ๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ๋ฉฐ ํ ์คํธ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํด IoC(์ ์ด ๋ฐ์ ) ํจํด์ ์ฌ์ฉํ๋ JavaScript ๋ชจ๋ ์์กด์ฑ ์ฃผ์ ๊ธฐ์ ์ ์ดํด๋ณด์ธ์. ์ค์ ์์ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐฐ์๋๋ค.
JavaScript ๋ชจ๋ ์์กด์ฑ ์ฃผ์ : IoC ํจํด ํ์ฉ
๋์์์ด ์งํํ๋ JavaScript ๊ฐ๋ฐ ํ๊ฒฝ์์ ํ์ฅ ๊ฐ๋ฅํ๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ๋ฉฐ ํ ์คํธ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ์ด๋ฅผ ๋ฌ์ฑํ๋ ๋ฐ ์์ด ์ค์ํ ์ธก๋ฉด ์ค ํ๋๋ ํจ๊ณผ์ ์ธ ๋ชจ๋ ๊ด๋ฆฌ ๋ฐ ๋์ปคํ๋ง์ ๋๋ค. ๊ฐ๋ ฅํ IoC(์ ์ด ๋ฐ์ ) ํจํด์ธ DI(์์กด์ฑ ์ฃผ์ )๋ ๋ชจ๋ ๊ฐ์ ์์กด์ฑ์ ๊ด๋ฆฌํ๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ฌ ๋์ฑ ์ ์ฐํ๊ณ ๋ณต์๋ ฅ ์๋ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋ง๋ญ๋๋ค.
์์กด์ฑ ์ฃผ์ ๋ฐ ์ ์ด ๋ฐ์ ์ดํด
JavaScript ๋ชจ๋ DI์ ๊ตฌ์ฒด์ ์ธ ๋ด์ฉ์ ๋ค์ด๊ฐ๊ธฐ ์ ์ IoC์ ๊ธฐ๋ณธ ์๋ฆฌ๋ฅผ ํ์ ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ ํต์ ์ผ๋ก ๋ชจ๋(๋๋ ํด๋์ค)์ ํด๋น ์์กด์ฑ์ ์์ฑํ๊ฑฐ๋ ํ๋ํ๋ ์ฑ ์์ ๊ฐ์ง๋๋ค. ์ด๋ฌํ ๊ธด๋ฐํ ๊ฒฐํฉ์ ์ฝ๋๋ฅผ ์ทจ์ฝํ๊ฒ ๋ง๋ค๊ณ ํ ์คํธํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค๋ฉฐ ๋ณ๊ฒฝ์ ์ ํญํ๊ฒ ๋ง๋ญ๋๋ค. IoC๋ ์ด๋ฌํ ํจ๋ฌ๋ค์์ ๋ค์ง์ต๋๋ค.
์ ์ด ๋ฐ์ (IoC)์ ๊ฐ์ฒด ์์ฑ ๋ฐ ์์กด์ฑ ๊ด๋ฆฌ ์ ์ด๊ฐ ๋ชจ๋ ์์ฒด์์ ์ธ๋ถ ์ํฐํฐ(์ผ๋ฐ์ ์ผ๋ก ์ปจํ ์ด๋ ๋๋ ํ๋ ์์ํฌ)๋ก ๋ฐ์ ๋๋ ์ค๊ณ ์์น์ ๋๋ค. ์ด ์ปจํ ์ด๋๋ ๋ชจ๋์ ํ์ํ ์์กด์ฑ์ ์ ๊ณตํ๋ ์ฑ ์์ ๊ฐ์ง๋๋ค.
์์กด์ฑ ์ฃผ์ (DI)์ IoC์ ํน์ ๊ตฌํ์ผ๋ก, ๋ชจ๋์ด ์์กด์ฑ์ ์์ฑํ๊ฑฐ๋ ์กฐํํ๋ ๋์ ์์กด์ฑ์ด ๋ชจ๋์ ์ ๊ณต(์ฃผ์ )๋ฉ๋๋ค. ์ด ์ฃผ์ ์ ๋์ค์ ์ดํด๋ณด๊ฒ ์ง๋ง ์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ์๊ฐํด ๋ณด์ธ์. ์๋์ฐจ๊ฐ ์์ฒด ์์ง์ ๊ตฌ์ถํ๋ ๋์ (๊ธด๋ฐํ ๊ฒฐํฉ) ์ ๋ฌธ ์์ง ์ ์กฐ์ ์ฒด๋ก๋ถํฐ ์์ง์ ๋ฐ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค(DI). ์๋์ฐจ๋ ์์ง์ด *์ด๋ป๊ฒ* ๊ตฌ์ถ๋๋์ง ์ ํ์ ์์ด ์ ์๋ ์ธํฐํ์ด์ค์ ๋ฐ๋ผ ์๋ํ๋ค๋ ๊ฒ๋ง ์๋ฉด ๋ฉ๋๋ค.
์์กด์ฑ ์ฃผ์ ์ ์ด์
JavaScript ํ๋ก์ ํธ์์ DI๋ฅผ ๊ตฌํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ง์ ์ด์ ์ด ์์ต๋๋ค.
- ๋ชจ๋์ฑ ํฅ์: ๋ชจ๋์ ๋์ฑ ๋ ๋ฆฝ์ ์ด๊ณ ํต์ฌ ์ฑ ์์ ์ง์ค๋ฉ๋๋ค. ์์กด์ฑ ์์ฑ ๋๋ ๊ด๋ฆฌ์ ๋ ์ฝํ ์์ต๋๋ค.
- ํ ์คํธ ๊ฐ๋ฅ์ฑ ํฅ์: DI๋ฅผ ์ฌ์ฉํ๋ฉด ํ ์คํธ ์ค์ ์ค์ ์์กด์ฑ์ ๋ชจ์ ๊ตฌํ์ผ๋ก ์ฝ๊ฒ ๋ฐ๊ฟ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ ์ด๋ ํ๊ฒฝ์์ ๊ฐ๋ณ ๋ชจ๋์ ๊ฒฉ๋ฆฌํ๊ณ ํ ์คํธํ ์ ์์ต๋๋ค. ์ธ๋ถ API์ ์์กดํ๋ ๊ตฌ์ฑ ์์๋ฅผ ํ ์คํธํ๋ค๊ณ ์์ํด ๋ณด์ธ์. DI๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ์ API ์๋ต์ ์ฃผ์ ํ์ฌ ํ ์คํธ ์ค์ ์ค์ ๋ก ์ธ๋ถ ์๋น์ค๋ฅผ ํธ์ถํ ํ์๊ฐ ์์ต๋๋ค.
- ๊ฒฐํฉ๋ ๊ฐ์: DI๋ ๋ชจ๋ ๊ฐ์ ๋์จํ ๊ฒฐํฉ์ ์ด์งํฉ๋๋ค. ํ ๋ชจ๋์ ๋ณ๊ฒฝ ์ฌํญ์ ํด๋น ๋ชจ๋์ ์์กดํ๋ ๋ค๋ฅธ ๋ชจ๋์ ์ํฅ์ ๋ฏธ์น ๊ฐ๋ฅ์ฑ์ด ์ ์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฝ๋๋ฒ ์ด์ค๊ฐ ์์ ์ ๋์ฑ ํ๋ ฅ์ ์ผ๋ก ๋์ํ ์ ์์ต๋๋ค.
- ์ฌ์ฌ์ฉ์ฑ ํฅ์: ๋ถ๋ฆฌ๋ ๋ชจ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ์ด๋ ์์ ํ ๋ค๋ฅธ ํ๋ก์ ํธ์์๋ ๋ ์ฝ๊ฒ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ธด๋ฐํ ์์กด์ฑ์ด ์๋ ์ ์ ์๋ ๋ชจ๋์ ๋ค์ํ ์ปจํ ์คํธ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
- ์ ์ง ๊ด๋ฆฌ ๊ฐ์ํ: ๋ชจ๋์ด ์ ๋ถ๋ฆฌ๋๊ณ ํ ์คํธ ๊ฐ๋ฅํ๋ฉด ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋ ์ฝ๊ฒ ์ดํดํ๊ณ ๋๋ฒ๊ทธํ๊ณ ์ ์ง ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ์ ์ฐ์ฑ ํฅ์: DI๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋์ ์์ ํ์ง ์๊ณ ๋ ์์กด์ฑ์ ๋ค๋ฅธ ๊ตฌํ ๊ฐ์ ์ฝ๊ฒ ์ ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์์กด์ฑ ์ฃผ์ ๊ตฌ์ฑ์ ๋ณ๊ฒฝํ๊ธฐ๋ง ํ๋ฉด ๋ค๋ฅธ ๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ๋ฐ์ดํฐ ์คํ ๋ฆฌ์ง ๋ฉ์ปค๋์ฆ ๊ฐ์ ์ ํํ ์ ์์ต๋๋ค.
JavaScript ๋ชจ๋์ ์์กด์ฑ ์ฃผ์ ๊ธฐ์
JavaScript๋ ๋ชจ๋์์ DI๋ฅผ ๊ตฌํํ๋ ์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๊ฐ์ฅ ์ผ๋ฐ์ ์ด๊ณ ํจ๊ณผ์ ์ธ ๊ธฐ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1. ์์ฑ์ ์ฃผ์
์์ฑ์ ์ฃผ์ ์ ์์กด์ฑ์ ๋ชจ๋์ ์์ฑ์์ ๋ํ ์ธ์๋ก ์ ๋ฌํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ด๊ฒ์ ๋๋ฆฌ ์ฌ์ฉ๋๊ณ ์ผ๋ฐ์ ์ผ๋ก ๊ถ์ฅ๋๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค.
์:
// ๋ชจ๋: UserProfileService
class UserProfileService {
constructor(apiClient) {
this.apiClient = apiClient;
}
async getUserProfile(userId) {
return this.apiClient.fetch(`/users/${userId}`);
}
}
// ์์กด์ฑ: ApiClient (๊ฐ์ ๋ ๊ตฌํ)
class ApiClient {
async fetch(url) {
// ...fetch ๋๋ axios๋ฅผ ์ฌ์ฉํ๋ ๊ตฌํ...
return fetch(url).then(response => response.json()); // ๋จ์ํ๋ ์์
}
}
// DI๋ฅผ ์ฌ์ฉํ ์ฌ์ฉ๋ฒ:
const apiClient = new ApiClient();
const userProfileService = new UserProfileService(apiClient);
// ์ด์ userProfileService๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
userProfileService.getUserProfile(123).then(profile => console.log(profile));
์ด ์์ ์์ `UserProfileService`๋ `ApiClient`์ ์์กดํฉ๋๋ค. ๋ด๋ถ์ ์ผ๋ก `ApiClient`๋ฅผ ์์ฑํ๋ ๋์ ์์ฑ์ ์ธ์๋ก ๋ฐ์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํ ์คํธ๋ฅผ ์ํด `ApiClient` ๊ตฌํ์ ์ฝ๊ฒ ๊ต์ฒดํ๊ฑฐ๋ `UserProfileService`๋ฅผ ์์ ํ์ง ์๊ณ ๋ค๋ฅธ API ํด๋ผ์ด์ธํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
2. ์ธํฐ ์ฃผ์
์ธํฐ ์ฃผ์ ์ ์ธํฐ ๋ฉ์๋(์์ฑ์ ์ค์ ํ๋ ๋ฉ์๋)๋ฅผ ํตํด ์์กด์ฑ์ ์ ๊ณตํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ์์ฑ์ ์ฃผ์ ๋ณด๋ค ๋ ์ผ๋ฐ์ ์ด์ง๋ง ๊ฐ์ฒด ์์ฑ ์ ์์กด์ฑ์ด ํ์ํ์ง ์์ ์ ์๋ ํน์ ์๋๋ฆฌ์ค์์ ์ ์ฉํ ์ ์์ต๋๋ค.
์:
class ProductCatalog {
constructor() {
this.dataFetcher = null;
}
setDataFetcher(dataFetcher) {
this.dataFetcher = dataFetcher;
}
async getProducts() {
if (!this.dataFetcher) {
throw new Error("๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋๊ตฌ๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค.");
}
return this.dataFetcher.fetchProducts();
}
}
// ์ธํฐ ์ฃผ์
์ ์ฌ์ฉํ ์ฌ์ฉ๋ฒ:
const productCatalog = new ProductCatalog();
// ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ํ ์ผ๋ถ ๊ตฌํ
const someFetcher = {
fetchProducts: async () => {
return [{
"id": 1,
"name": "Product 1"
}];
}
}
productCatalog.setDataFetcher(someFetcher);
productCatalog.getProducts().then(products => console.log(products));
์ฌ๊ธฐ์ `ProductCatalog`๋ `setDataFetcher` ๋ฉ์๋๋ฅผ ํตํด `dataFetcher` ์์กด์ฑ์ ๋ฐ์ต๋๋ค. ์ด๋ฅผ ํตํด `ProductCatalog` ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ์์ ๋์ค์ ์์กด์ฑ์ ์ค์ ํ ์ ์์ต๋๋ค.
3. ์ธํฐํ์ด์ค ์ฃผ์
์ธํฐํ์ด์ค ์ฃผ์ ์ ๋ชจ๋์ด ์์กด์ฑ์ ๋ํ ์ธํฐ ๋ฉ์๋๋ฅผ ์ ์ํ๋ ํน์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋๋ก ์๊ตฌํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ JavaScript์ ๋์ ํน์ฑ์ผ๋ก ์ธํด ๋ ์ผ๋ฐ์ ์ด์ง๋ง TypeScript ๋๋ ๋ค๋ฅธ ์ ํ ์์คํ ์ ์ฌ์ฉํ์ฌ ์ ์ฉํ ์ ์์ต๋๋ค.
์(TypeScript):
interface ILogger {
log(message: string): void;
}
interface ILoggable {
setLogger(logger: ILogger): void;
}
class MyComponent implements ILoggable {
private logger: ILogger;
setLogger(logger: ILogger) {
this.logger = logger;
}
doSomething() {
this.logger.log("๋ฌด์ธ๊ฐ๋ฅผ ์ํ ์ค...");
}
}
class ConsoleLogger implements ILogger {
log(message: string) {
console.log(message);
}
}
// ์ธํฐํ์ด์ค ์ฃผ์
์ ์ฌ์ฉํ ์ฌ์ฉ๋ฒ:
const myComponent = new MyComponent();
const consoleLogger = new ConsoleLogger();
myComponent.setLogger(consoleLogger);
myComponent.doSomething();
์ด TypeScript ์์ ์์ `MyComponent`๋ `ILoggable` ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ฌ `setLogger` ๋ฉ์๋๋ฅผ ๊ฐ๋๋ก ์๊ตฌํฉ๋๋ค. `ConsoleLogger`๋ `ILogger` ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ๋ชจ๋๊ณผ ํด๋น ์์กด์ฑ ๊ฐ์ ๊ณ์ฝ์ ๊ฐ์ ํฉ๋๋ค.
4. ๋ชจ๋ ๊ธฐ๋ฐ ์์กด์ฑ ์ฃผ์ (ES ๋ชจ๋ ๋๋ CommonJS ์ฌ์ฉ)
JavaScript์ ๋ชจ๋ ์์คํ (ES ๋ชจ๋ ๋ฐ CommonJS)์ DI๋ฅผ ๊ตฌํํ๋ ์์ฐ์ค๋ฌ์ด ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๋ชจ๋์ ์์กด์ฑ์ ๊ฐ์ ธ์จ ๋ค์ ํด๋น ๋ชจ๋ ๋ด์ ํจ์ ๋๋ ํด๋์ค์ ์ธ์๋ก ์ ๋ฌํ ์ ์์ต๋๋ค.
์(ES ๋ชจ๋):
// api-client.js
export async function fetchData(url) {
const response = await fetch(url);
return response.json();
}
// user-service.js
import { fetchData } from './api-client.js';
export async function getUser(userId) {
return fetchData(`/users/${userId}`);
}
// component.js
import { getUser } from './user-service.js';
async function displayUser(userId) {
const user = await getUser(userId);
console.log(user);
}
displayUser(123);
์ด ์์ ์์ `user-service.js`๋ `api-client.js`์์ `fetchData`๋ฅผ ๊ฐ์ ธ์ต๋๋ค. `component.js`๋ `user-service.js`์์ `getUser`๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ์ด๋ฅผ ํตํด ํ ์คํธ ๋๋ ๋ค๋ฅธ ๋ชฉ์ ์ผ๋ก `api-client.js`๋ฅผ ๋ค๋ฅธ ๊ตฌํ์ผ๋ก ์ฝ๊ฒ ๊ต์ฒดํ ์ ์์ต๋๋ค.
์์กด์ฑ ์ฃผ์ ์ปจํ ์ด๋(DI ์ปจํ ์ด๋)
์์ ๊ธฐ์ ์ ๊ฐ๋จํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํ์ง๋ง ๋ ํฐ ํ๋ก์ ํธ๋ DI ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. DI ์ปจํ ์ด๋๋ ์์กด์ฑ ์์ฑ ๋ฐ ๊ด๋ฆฌ ํ๋ก์ธ์ค๋ฅผ ์๋ํํ๋ ํ๋ ์์ํฌ์ ๋๋ค. ์์กด์ฑ์ ๊ตฌ์ฑํ๊ณ ํด๊ฒฐํ ์ ์๋ ์ค์ ์์น๋ฅผ ์ ๊ณตํ์ฌ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋ณด๋ค ์ฒด๊ณ์ ์ด๊ณ ์ ์ง ๊ด๋ฆฌํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
์ผ๋ถ ์ธ๊ธฐ ์๋ JavaScript DI ์ปจํ ์ด๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- InversifyJS: TypeScript ๋ฐ JavaScript๋ฅผ ์ํ ๊ฐ๋ ฅํ๊ณ ๊ธฐ๋ฅ์ด ํ๋ถํ DI ์ปจํ ์ด๋์ ๋๋ค. ์์ฑ์ ์ฃผ์ , ์ธํฐ ์ฃผ์ ๋ฐ ์ธํฐํ์ด์ค ์ฃผ์ ์ ์ง์ํฉ๋๋ค. TypeScript์ ํจ๊ป ์ฌ์ฉํ ๋ ์ ํ ์์ ์ฑ์ ์ ๊ณตํฉ๋๋ค.
- Awilix: Node.js๋ฅผ ์ํ ์ค์ฉ์ ์ด๊ณ ๊ฐ๋ฒผ์ด DI ์ปจํ ์ด๋์ ๋๋ค. ๋ค์ํ ์ฃผ์ ์ ๋ต์ ์ง์ํ๊ณ Express.js์ ๊ฐ์ ์ธ๊ธฐ ์๋ ํ๋ ์์ํฌ์ ํ๋ฅญํ๊ฒ ํตํฉ๋ฉ๋๋ค.
- tsyringe: TypeScript ๋ฐ JavaScript๋ฅผ ์ํ ๊ฐ๋ฒผ์ด DI ์ปจํ ์ด๋์ ๋๋ค. ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํ์ฉํ์ฌ ์์กด์ฑ ๋ฑ๋ก ๋ฐ ํด๊ฒฐ์ ์ํํ๋ฏ๋ก ๊น๋ํ๊ณ ๊ฐ๊ฒฐํ ๊ตฌ๋ฌธ์ ์ ๊ณตํฉ๋๋ค.
์(InversifyJS):
// ํ์ํ ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ
import "reflect-metadata";
import { Container, injectable, inject } from "inversify";
// ์ธํฐํ์ด์ค ์ ์
interface IUserRepository {
getUser(id: number): Promise;
}
interface IUserService {
getUserProfile(id: number): Promise;
}
// ์ธํฐํ์ด์ค ๊ตฌํ
@injectable()
class UserRepository implements IUserRepository {
async getUser(id: number): Promise {
// ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฌ์ฉ์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์๋ฎฌ๋ ์ด์
return new Promise((resolve) => {
setTimeout(() => {
resolve({ id: id, name: "John Doe", email: "john.doe@example.com" });
}, 500);
});
}
}
@injectable()
class UserService implements IUserService {
private userRepository: IUserRepository;
constructor(@inject(TYPES.IUserRepository) userRepository: IUserRepository) {
this.userRepository = userRepository;
}
async getUserProfile(id: number): Promise {
return this.userRepository.getUser(id);
}
}
// ์ธํฐํ์ด์ค์ ๋ํ ๊ธฐํธ ์ ์
const TYPES = {
IUserRepository: Symbol.for("IUserRepository"),
IUserService: Symbol.for("IUserService"),
};
// ์ปจํ
์ด๋ ์์ฑ
const container = new Container();
container.bind(TYPES.IUserRepository).to(UserRepository);
container.bind(TYPES.IUserService).to(UserService);
// UserService ํด๊ฒฐ
const userService = container.get(TYPES.IUserService);
// UserService ์ฌ์ฉ
userService.getUserProfile(1).then(user => console.log(user));
์ด InversifyJS ์์ ์์๋ `UserRepository` ๋ฐ `UserService`์ ๋ํ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ `UserRepository` ๋ฐ `UserService` ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํฉ๋๋ค. `@injectable()` ๋ฐ์ฝ๋ ์ดํฐ๋ ์ด๋ฌํ ํด๋์ค๋ฅผ ์ฃผ์ ๊ฐ๋ฅ์ผ๋ก ํ์ํฉ๋๋ค. `@inject()` ๋ฐ์ฝ๋ ์ดํฐ๋ `UserService` ์์ฑ์์ ์ฃผ์ ํ ์์กด์ฑ์ ์ง์ ํฉ๋๋ค. ์ปจํ ์ด๋๋ ์ธํฐํ์ด์ค๋ฅผ ํด๋น ๊ตฌํ์ ๋ฐ์ธ๋ฉํ๋๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ์ฌ `UserService`๋ฅผ ํด๊ฒฐํ๊ณ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ํ๋กํ์ ๊ฒ์ํฉ๋๋ค. ์ด ์์ ์์๋ `UserService`์ ์์กด์ฑ์ ๋ช ํํ๊ฒ ์ ์ํ๊ณ ์์กด์ฑ์ ์ฝ๊ฒ ํ ์คํธํ๊ณ ๊ต์ฒดํ ์ ์๋๋ก ํฉ๋๋ค. `TYPES`๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ์ ๋งคํํ๋ ํค ์ญํ ์ ํฉ๋๋ค.
JavaScript์์ ์์กด์ฑ ์ฃผ์ ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
JavaScript ํ๋ก์ ํธ์์ DI๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ณ ๋ คํ์ธ์.
- ์์ฑ์ ์ฃผ์ ์ ํธ: ์์ฑ์ ์ฃผ์ ์ ๋ชจ๋์ ์์กด์ฑ์ ๋ฏธ๋ฆฌ ๋ช ํํ๊ฒ ์ ์ํ๋ฏ๋ก ์ผ๋ฐ์ ์ผ๋ก ์ ํธ๋๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค.
- ์ํ ์์กด์ฑ ๋ฐฉ์ง: ์ํ ์์กด์ฑ์ ๋ณต์กํ๊ณ ๋๋ฒ๊ทธํ๊ธฐ ์ด๋ ค์ด ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค. ์ํ ์์กด์ฑ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ชจ๋์ ์ ์คํ๊ฒ ์ค๊ณํ์ธ์. ์ด๋ฅผ ์ํด์๋ ๋ฆฌํฉํฐ๋งํ๊ฑฐ๋ ์ค๊ฐ ๋ชจ๋์ ๋์ ํด์ผ ํ ์ ์์ต๋๋ค.
- ์ธํฐํ์ด์ค ์ฌ์ฉ(ํนํ TypeScript ์ฌ์ฉ ์): ์ธํฐํ์ด์ค๋ ๋ชจ๋๊ณผ ํด๋น ์์กด์ฑ ๊ฐ์ ๊ณ์ฝ์ ์ ๊ณตํ์ฌ ์ฝ๋ ์ ์ง ๊ด๋ฆฌ์ฑ ๋ฐ ํ ์คํธ ๊ฐ๋ฅ์ฑ์ ํฅ์์ํต๋๋ค.
- ๋ชจ๋์ ์๊ณ ์ง์ค์ ์ผ๋ก ์ ์ง: ๋ ์๊ณ ์ง์ค์ ์ธ ๋ชจ๋์ ์ดํด, ํ ์คํธ ๋ฐ ์ ์ง ๊ด๋ฆฌํ๊ธฐ ์ฝ์ต๋๋ค. ๋ํ ์ฌ์ฌ์ฉ์ฑ์ ์ด์งํฉ๋๋ค.
- ๋ ํฐ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ DI ์ปจํ ์ด๋ ์ฌ์ฉ: DI ์ปจํ ์ด๋๋ ๋ ํฐ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์กด์ฑ ๊ด๋ฆฌ๋ฅผ ํฌ๊ฒ ๊ฐ์ํํ ์ ์์ต๋๋ค.
- ๋จ์ ํ ์คํธ ์์ฑ: ๋จ์ ํ ์คํธ๋ ๋ชจ๋์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๊ณ DI๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑ๋์๋์ง ํ์ธํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
- ๋จ์ผ ์ฑ ์ ์์น(SRP) ์ ์ฉ: ๊ฐ ๋ชจ๋์ด ๋ณ๊ฒฝ๋ ์ด์ ๊ฐ ํ๋๋ง ์๋์ง ํ์ธํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด ์์กด์ฑ ๊ด๋ฆฌ๊ฐ ๊ฐ์ํ๋๊ณ ๋ชจ๋์ฑ์ด ์ด์ง๋ฉ๋๋ค.
ํผํด์ผ ํ ์ผ๋ฐ์ ์ธ ์ํฐ ํจํด
๋ช ๊ฐ์ง ์ํฐ ํจํด์ ์์กด์ฑ ์ฃผ์ ์ ํจ๊ณผ๋ฅผ ์ ํดํ ์ ์์ต๋๋ค. ์ด๋ฌํ ํจ์ ์ ํผํ๋ฉด ๋์ฑ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅํ๊ณ ๊ฐ๋ ฅํ ์ฝ๋๊ฐ ์์ฑ๋ฉ๋๋ค.
- ์๋น์ค ๋ก์ผ์ดํฐ ํจํด: ๊ฒ์ผ๋ก๋ ๋น์ทํด ๋ณด์ด์ง๋ง ์๋น์ค ๋ก์ผ์ดํฐ ํจํด์ ์ฌ์ฉํ๋ฉด ๋ชจ๋์ด ์ค์ ๋ ์ง์คํธ๋ฆฌ์์ ์์กด์ฑ์ *์์ฒญ*ํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ์ ํ ์์กด์ฑ์ด ์จ๊ฒจ์ง๊ณ ํ ์คํธ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ญ๋๋ค. DI๋ ์์กด์ฑ์ ๋ช ์์ ์ผ๋ก ์ฃผ์ ํ์ฌ ํ์๋๋๋ก ํฉ๋๋ค.
- ์ ์ญ ์ํ: ์ ์ญ ๋ณ์ ๋๋ ์ฑ๊ธํค ์ธ์คํด์ค์ ์์กดํ๋ฉด ์จ๊ฒจ์ง ์์กด์ฑ์ด ์์ฑ๋๊ณ ๋ชจ๋์ ํ ์คํธํ๊ธฐ ์ด๋ ค์์ง ์ ์์ต๋๋ค. DI๋ ๋ช ์์ ์ธ ์์กด์ฑ ์ ์ธ์ ๊ถ์ฅํฉ๋๋ค.
- ๊ณผ๋ํ ์ถ์ํ: ๋ถํ์ํ ์ถ์ํ๋ฅผ ๋์ ํ๋ฉด ์ค์ํ ์ด์ ์ ์ ๊ณตํ์ง ์๊ณ ์ฝ๋๋ฒ ์ด์ค๊ฐ ๋ณต์กํด์ง ์ ์์ต๋๋ค. DI๋ฅผ ์ ์คํ๊ฒ ์ ์ฉํ๊ณ ๊ฐ์ฅ ๋ง์ ๊ฐ์น๋ฅผ ์ ๊ณตํ๋ ์์ญ์ ์ง์คํ์ธ์.
- ์ปจํ ์ด๋์ ๋ํ ๊ธด๋ฐํ ๊ฒฐํฉ: ๋ชจ๋์ DI ์ปจํ ์ด๋ ์์ฒด์ ๊ธด๋ฐํ๊ฒ ๊ฒฐํฉํ์ง ๋ง์ธ์. ์ด์์ ์ผ๋ก ๋ชจ๋์ ์ปจํ ์ด๋ ์์ด๋ ์๋ํ ์ ์์ด์ผ ํ๋ฉฐ ํ์ํ ๊ฒฝ์ฐ ๊ฐ๋จํ ์์ฑ์ ์ฃผ์ ๋๋ ์ธํฐ ์ฃผ์ ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- ์์ฑ์ ๊ณผ๋ ์ฃผ์ : ์์ฑ์์ ๋๋ฌด ๋ง์ ์์กด์ฑ์ด ์ฃผ์ ๋๋ฉด ๋ชจ๋์ด ๋๋ฌด ๋ง์ ์์ ์ ์ํํ๋ ค๊ณ ํ๋ ๊ฒ์ผ ์ ์์ต๋๋ค. ๋ ์๊ณ ์ง์ค์ ์ธ ๋ชจ๋๋ก ๋ถํดํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
์ค์ ์์ ๋ฐ ์ฌ์ฉ ์ฌ๋ก
์์กด์ฑ ์ฃผ์ ์ ๊ด๋ฒ์ํ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฉํ ์ ์์ต๋๋ค. ๋ช ๊ฐ์ง ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์น ํ๋ ์์ํฌ(์: React, Angular, Vue.js): ๋ง์ ์น ํ๋ ์์ํฌ๋ DI๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ์ฑ ์์, ์๋น์ค ๋ฐ ๊ธฐํ ์์กด์ฑ์ ๊ด๋ฆฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด Angular์ DI ์์คํ ์ ์ฌ์ฉํ๋ฉด ์๋น์ค๋ฅผ ๊ตฌ์ฑ ์์์ ์ฝ๊ฒ ์ฃผ์ ํ ์ ์์ต๋๋ค.
- Node.js ๋ฐฑ์๋: DI๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, API ํด๋ผ์ด์ธํธ ๋ฐ ๋ก๊น ์๋น์ค์ ๊ฐ์ Node.js ๋ฐฑ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์กด์ฑ์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ๋ฐ์คํฌํฑ ์ ํ๋ฆฌ์ผ์ด์ (์: Electron): DI๋ ํ์ผ ์์คํ ์ก์ธ์ค, ๋คํธ์ํฌ ํต์ ๋ฐ UI ๊ตฌ์ฑ ์์์ ๊ฐ์ Electron์ผ๋ก ๋น๋๋ ๋ฐ์คํฌํฑ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์กด์ฑ์ ๊ด๋ฆฌํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ํ ์คํ : DI๋ ํจ๊ณผ์ ์ธ ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํ๋ ๋ฐ ํ์์ ์ ๋๋ค. ๋ชจ์ ์์กด์ฑ์ ์ฃผ์ ํ์ฌ ์ ์ด๋ ํ๊ฒฝ์์ ๊ฐ๋ณ ๋ชจ๋์ ๊ฒฉ๋ฆฌํ๊ณ ํ ์คํธํ ์ ์์ต๋๋ค.
- ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ: ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ์์ DI๋ ์๋น์ค ๊ฐ์ ์์กด์ฑ์ ๊ด๋ฆฌํ์ฌ ๋์จํ ๊ฒฐํฉ๊ณผ ๋ ๋ฆฝ์ ์ธ ๋ฐฐํฌ ๊ฐ๋ฅ์ฑ์ ์ด์งํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ์๋ฒ๋ฆฌ์ค ํจ์(์: AWS Lambda, Azure Functions): ์๋ฒ๋ฆฌ์ค ํจ์ ๋ด์์๋ DI ์์น์ ์ฝ๋์ ํ ์คํธ ๊ฐ๋ฅ์ฑ๊ณผ ์ ์ง ๊ด๋ฆฌ์ฑ์ ๋ณด์ฅํ๊ณ ๊ตฌ์ฑ ๋ฐ ์ธ๋ถ ์๋น์ค๋ฅผ ์ฃผ์ ํ ์ ์์ต๋๋ค.
์์ ์๋๋ฆฌ์ค: ๊ตญ์ ํ(i18n)
์ฌ๋ฌ ์ธ์ด๋ฅผ ์ง์ํด์ผ ํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํด ๋ณด์ธ์. ์ฝ๋๋ฒ ์ด์ค ์ ์ฒด์ ์ธ์ด๋ณ ํ ์คํธ๋ฅผ ํ๋ ์ฝ๋ฉํ๋ ๋์ DI๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ๋ก์บ์ ๊ธฐ๋ฐ์ผ๋ก ์ ์ ํ ๋ฒ์ญ์ ์ ๊ณตํ๋ ์ง์ญํ ์๋น์ค๋ฅผ ์ฃผ์ ํ ์ ์์ต๋๋ค.
// ILocalizationService ์ธํฐํ์ด์ค
interface ILocalizationService {
translate(key: string): string;
}
// EnglishLocalizationService ๊ตฌํ
class EnglishLocalizationService implements ILocalizationService {
private translations = {
"greeting": "Hello",
"goodbye": "Goodbye",
};
translate(key: string): string {
return this.translations[key] || key;
}
}
// SpanishLocalizationService ๊ตฌํ
class SpanishLocalizationService implements ILocalizationService {
private translations = {
"greeting": "Hola",
"goodbye": "Adiรณs",
};
translate(key: string): string {
return this.translations[key] || key;
}
}
// ์ง์ญํ ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ ๊ตฌ์ฑ ์์
class GreetingComponent {
private localizationService: ILocalizationService;
constructor(localizationService: ILocalizationService) {
this.localizationService = localizationService;
}
render() {
const greeting = this.localizationService.translate("greeting");
return `${greeting}
`;
}
}
// DI๋ฅผ ์ฌ์ฉํ ์ฌ์ฉ๋ฒ
const englishLocalizationService = new EnglishLocalizationService();
const spanishLocalizationService = new SpanishLocalizationService();
// ์ฌ์ฉ์์ ๋ก์บ์ ๋ฐ๋ผ ์ ์ ํ ์๋น์ค ์ฃผ์
const greetingComponent = new GreetingComponent(englishLocalizationService); // ๋๋ spanishLocalizationService
console.log(greetingComponent.render());
์ด ์์ ์์๋ DI๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ๊ธฐ๋ณธ ์ค์ ๋๋ ์ง๋ฆฌ์ ์์น์ ๋ฐ๋ผ ๋ค์ํ ์ง์ญํ ๊ตฌํ ๊ฐ์ ์ฝ๊ฒ ์ ํํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ํ ๊ตญ์ ์ฌ์ฉ์์๊ฒ ์ ์ํ ์ ์๋๋ก ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
๊ฒฐ๋ก
์์กด์ฑ ์ฃผ์ ์ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์์ธ, ์ ์ง ๊ด๋ฆฌ์ฑ ๋ฐ ํ ์คํธ ๊ฐ๋ฅ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์๋ ๊ฐ๋ ฅํ ๊ธฐ์ ์ ๋๋ค. IoC ์์น์ ์์ฉํ๊ณ ์์กด์ฑ์ ์ ์คํ๊ฒ ๊ด๋ฆฌํ๋ฉด ๋์ฑ ์ ์ฐํ๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ ๋ณต์๋ ฅ ์๋ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋๊ท๋ชจ ์ํฐํ๋ผ์ด์ฆ ์์คํ ์ ๊ตฌ์ถํ๋ DI ์์น์ ์ดํดํ๊ณ ์ ์ฉํ๋ ๊ฒ์ ๋ชจ๋ JavaScript ๊ฐ๋ฐ์์๊ฒ ๊ฐ์น ์๋ ๊ธฐ์ ์ ๋๋ค.
๋ค์ํ DI ๊ธฐ์ ๋ฐ DI ์ปจํ ์ด๋๋ฅผ ์คํํ์ฌ ํ๋ก์ ํธ์ ์๊ตฌ ์ฌํญ์ ๊ฐ์ฅ ์ ํฉํ ์ ๊ทผ ๋ฐฉ์์ ์ฐพ์๋ณด์ธ์. ์์กด์ฑ ์ฃผ์ ์ ์ด์ ์ ๊ทน๋ํํ๊ธฐ ์ํด ๊นจ๋ํ๊ณ ๋ชจ๋์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ค์ํ๋ ๋ฐ ์ง์คํ์ธ์.