Front-end/Good Front

๐Ÿ’ก ํ”„๋ก ํŠธ์—”๋“œ์—์„œ IoC๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

xeunnie 2025. 2. 21. 01:00
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ’ก ํ”„๋ก ํŠธ์—”๋“œ์—์„œ 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๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋” ๊นจ๋—ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์„ธ์š”.

๐ŸŒท์ „์„ค์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด๋ด…์‹œ๋‹น!๐ŸŒท

728x90
๋ฐ˜์‘ํ˜•