๐ก ํ๋ก ํธ์๋์์ IoC๋ ๋ฌด์์ธ๊ฐ์?
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ํ๋ค ๋ณด๋ฉด **IoC(Inversion of Control, ์ ์ด์ ์ญ์ )**์ด๋ผ๋ ๊ฐ๋ ์ ๋ฃ๊ฒ ๋ ๋๊ฐ ์์ด์. ์ฒ์์๋ ์กฐ๊ธ ์์ํ ์ ์์ง๋ง, ์ค์ ๋ก IoC๋ ์ฝ๋์ ์ ์ฐ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ด๋ ์ค์ํ ๊ฐ๋ ์ด์์. ํ๋ก ํธ์๋์์๋ ์ฃผ๋ก ์์กด์ฑ ์ฃผ์ (Dependency Injection) ํจํด๊ณผ ํจ๊ป ์ด์ผ๊ธฐ๋๊ณค ํฉ๋๋ค. ์ด ๊ธ์์๋ IoC๊ฐ ๋ฌด์์ธ์ง, ํ๋ก ํธ์๋์์ ์ด๋ป๊ฒ ์ ์ฉํ ์ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ค๋ค๋ณผ๊ฒ์! ๐
IoC๋?
IoC๋ ์ ์ด๊ถ์ ๊ฐ๋ฐ์๊ฐ ์๋ ๋ค๋ฅธ ๊ณณ(์ฃผ๋ก ํ๋ ์์ํฌ ๋๋ ์ธ๋ถ ์ปดํฌ๋ํธ)์ ๋๊ฒจ์ฃผ๋ ๋ฐฉ์์ ์๋ฏธํด์. ์ ํต์ ์ธ ๋ฐฉ์์์๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ์ง๋ง, IoC๋ฅผ ํ์ฉํ๋ฉด ์ด ์์ ์ ํ๋ ์์ํฌ๋ ์ปจํ ์ด๋๊ฐ ๋์ ์ฒ๋ฆฌํฉ๋๋ค.
๐ ๏ธ IoC์ ํต์ฌ
1. ์ ์ด ํ๋ฆ์ ์ญ์ : ๊ฐ์ฒด์ ์์ฑ, ๊ด๋ฆฌ, ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ๋ค๋ฃจ๋ ๋์ ์ธ๋ถ์์ ๊ด๋ฆฌํ๊ฒ ๋ง๋ญ๋๋ค.
2. ์์กด์ฑ ์ฃผ์ (DI): ๊ฐ์ฒด๊ฐ ํ์ํ ์์กด์ฑ์ ์ธ๋ถ์์ ์ฃผ์ ๋ฐ์ต๋๋ค.
3. ์ ์ฐ์ฑ ์ฆ๊ฐ: ๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถฐ ์ฌ์ฌ์ฉ์ฑ๊ณผ ํ์ฅ์ฑ์ ๋์ ๋๋ค.
IoC์ ํ๋ก ํธ์๋ ์ ์ฉ ์ฌ๋ก
ํ๋ก ํธ์๋์์๋ IoC๋ฅผ ๋ค์ํ ํํ๋ก ์ ์ฉํ ์ ์์ด์. ๋ํ์ ์ธ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
1๏ธโฃ React์ Context API
React์์ IoC๋ Context API๋ฅผ ํตํด ํํ ๊ตฌํ๋ฉ๋๋ค. ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ํ์ ์ปดํฌ๋ํธ๋ก ์์กด์ฑ์ ์ฃผ์ ํ๋ ๋ฐฉ์์ผ๋ก, ์ปดํฌ๋ํธ ๊ณ์ธต ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํฉ๋๋ค.
import React, { createContext, useContext } from "react";
// Context ์์ฑ
const ThemeContext = createContext();
const ThemeProvider = ({ children }) => {
const theme = "dark";
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
);
};
// IoC: ์์กด์ฑ ์ฃผ์
const ThemedComponent = () => {
const theme = useContext(ThemeContext); // ์ธ๋ถ์์ ์ฃผ์ ๋ ์์กด์ฑ์ ์ฌ์ฉ
return <div>Current Theme: {theme}</div>;
};
const App = () => (
<ThemeProvider>
<ThemedComponent />
</ThemeProvider>
);
export default App;
• ์ด์ : ThemeContext๋ฅผ ํตํด theme ์์กด์ฑ์ด ํ์ ์ปดํฌ๋ํธ๋ก ์ฃผ์ ๋๋ฉฐ, ๊ฐ๋ฐ์๋ ์ง์ ๋ฐ์ดํฐ ์ ๋ฌ์ ๊ด๋ฆฌํ์ง ์์๋ ๋ฉ๋๋ค.
2๏ธโฃ DI ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ
์์กด์ฑ ์ฃผ์ ์ ๋ ์ฒด๊ณ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด InversifyJS ๊ฐ์ DI ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์๋ ์์ด์.
import "reflect-metadata";
import { Container, injectable, inject } from "inversify";
// ํด๋์ค ์ ์
@injectable()
class ApiService {
fetchData() {
return "Fetching Data!";
}
}
@injectable()
class AppService {
constructor(@inject(ApiService) private apiService) {}
execute() {
return this.apiService.fetchData();
}
}
// DI ์ปจํ ์ด๋ ์ค์
const container = new Container();
container.bind(ApiService).toSelf();
container.bind(AppService).toSelf();
// IoC: ์์กด์ฑ ์ฃผ์
const appService = container.get(AppService);
console.log(appService.execute()); // "Fetching Data!"
• ์ด์ : ์์กด์ฑ์ ์ธ๋ถ์์ ๊ด๋ฆฌํ๋ฏ๋ก ํ ์คํธ์ ์ฝ๋ ํ์ฅ์ด ์ฉ์ดํด์ง๋๋ค.
IoC์ ์ฅ์
• ๊ฒฐํฉ๋ ๊ฐ์: ๊ฐ์ฒด ๊ฐ ๊ฐํ ์์กด์ฑ์ ์ ๊ฑฐํ์ฌ ์ฝ๋์ ์ ์ฐ์ฑ์ ๋์ ๋๋ค.
• ์ฌ์ฌ์ฉ์ฑ ์ฆ๊ฐ: ์์กด์ฑ์ด ์ธ๋ถ์์ ์ฃผ์ ๋๋ฏ๋ก ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ค์ํ ์ํฉ์์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
• ํ ์คํธ ์ฉ์ด์ฑ: ์์กด์ฑ์ Mock์ผ๋ก ์ฝ๊ฒ ๋์ฒดํ ์ ์์ด ๋จ์ ํ ์คํธ ์์ฑ์ด ์ฌ์์ง๋๋ค.
IoC ์ ์ฉ ์ ์ฃผ์์
1. ๊ณผ๋ํ ์ถ์ํ ํผํ๊ธฐ: IoC๋ฅผ ์ง๋์น๊ฒ ์ฌ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ณ ์ดํดํ๊ธฐ ์ด๋ ค์์ง ์ ์์ต๋๋ค.
2. ๋ช ํํ ์์กด์ฑ ๊ด๋ฆฌ: ์ด๋ค ์์กด์ฑ์ด ์ด๋์ ๊ด๋ฆฌ๋๋์ง ๋ช ํํ ์ ์ํด์ผ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํฉ๋๋ค.
3. DI ์ปจํ ์ด๋ ์ค๋ฒํค๋: DI ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ฑ๋ฅ๊ณผ ์ด๊ธฐ ์ค์ ๋น์ฉ์ด ์ฆ๊ฐํ ์ ์์ผ๋ฏ๋ก ์ ์ ํ ์ ํํด์ผ ํฉ๋๋ค.
IoC๋ฅผ ์ ํ์ฉํ๋ ํ
1. Context API์ Redux ๊ฐ์ด ์ฐ๊ธฐ
Context API๋ก ์ ์ญ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ฉด์, ํ์ํ ๊ฒฝ์ฐ Redux์ ์ฐ๊ณํ์ฌ ๋ ๊ฐ๋ ฅํ ์ํ ๊ด๋ฆฌ ํจํด์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
2. Hooks ํ์ฉ
React์ useContext์ ๊ฐ์ ํ ์ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ๋ฉด IoC์ ๊ฒฐํฉํด ๋์ฑ ๊น๋ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
3. ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ํตํ ๊ด๋ฆฌ
์์กด์ฑ ์ฃผ์ ์ ๋ช ์์ ์ด์ง ์์ผ๋ฉด ๋ณต์กํด์ง ์ ์์ผ๋ฏ๋ก ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ํตํด ๊ด๋ฆฌํ์ธ์.
๊ฒฐ๋ก : IoC๋ ํ๋ก ํธ์๋์ ๋น๋ฐ ๋ณ๊ธฐ ๐ก๏ธ
IoC๋ ํ๋ก ํธ์๋์์ ์ ์ฐํ ์ฝ๋ ์์ฑ๊ณผ ์ ์ง๋ณด์๋ฅผ ์ํด ๋ฐ๋์ ์์์ผ ํ ๊ฐ๋ ์ ๋๋ค. React์ Context API, Redux, DI ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฑ์ ์ ์ ํ ํ์ฉํ๋ฉด ๋ชจ๋ ๊ฐ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
์ด์ IoC๋ฅผ ํ์ฉํ์ฌ ๋ ๊นจ๋ํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํด๋ณด์ธ์.
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น!๐ท
'Front-end > Good Front' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐จ๏ธ Giscus: GitHub ๊ธฐ๋ฐ์ ๋๊ธ ์์คํ (0) | 2025.03.06 |
---|---|
๐ gray-matter: Markdown ํ์ผ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ง๋ฒ ๋๊ตฌ (0) | 2025.03.05 |
Compound Components๋? ๐ก (0) | 2025.02.23 |