DI (Dependency Injection)


๐Ÿ–ฅ๏ธ DI(Dependency Injection)์ด๋ž€?

์†Œํ”„ํŠธ์›จ์–ด ๊ณตํ•™์—์„œ ๊ฐ์ฒด ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹  ํ•„์š”ํ•œ ๋‹ค๋ฅธ ๊ฐ์ฒด ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ์ˆ ์ด๋ฉฐ, ์ด๋Š” ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•œ ๊ฒƒ์„ ์Šค์Šค๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ณ , ์™ธ๋ถ€์—์„œ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.


๐Ÿ–ฅ๏ธ DI์™€ IoC์˜ ๊ด€๊ณ„์„ฑ

์ œ์–ด ๋ฐ˜์ „(Inversion of Control, IoC)์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ๋ฆ„์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ ์™ธ๋ถ€ ์‹œ์Šคํ…œ์ด ๋งก๋Š” ๊ฐœ๋…์ด๋ฉฐ, DI๋Š” ๊ทธ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ๋ณดํ†ต ๊ฐ์ฒด๋Š” ์ž์‹ ์ด ํ•„์š”ํ•œ ๊ฒƒ๋“ค์„ ์Šค์Šค๋กœ ๋งŒ๋“ค์ง€๋งŒ, ์ œ์–ด ๋ฐ˜์ „์—์„œ๋Š” ๊ทธ ์ผ์„ ์™ธ๋ถ€์—์„œ ๋Œ€์‹ ํ•œ๋‹ค. ์ฆ‰, ๊ฐ์ฒด๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒƒ์„ ์™ธ๋ถ€์—์„œ ์ฃผ์ž…๋ฐ›๋Š” ๋ฐฉ์‹์ธ DI์™€ IoC๋Š” ์„œ๋กœ ๋ฐ€์ ‘ํ•˜๊ฒŒ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค.


๐Ÿ–ฅ๏ธ DI์˜ ์žฅยท๋‹จ์ 

[์žฅ์ ]

  1. ๋ชจ๋“ˆ์„ฑ๊ณผ ์žฌ์‚ฌ์šฉ์„ฑ ๋†’์•„์ง
    • ์ฝ”๋“œ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•ด์„œ ๊ตฌํ˜„์ฒด๋ฅผ ์‰ฝ๊ฒŒ ๊ต์ฒด ๊ฐ€๋Šฅ.
    • ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Œ.
  2. ์œ ์ง€๋ณด์ˆ˜์„ฑ ์ข‹์Œ
    • ์˜์กด์„ฑ์ด ๋ช…์‹œ์ ์œผ๋กœ ๊ด€๋ฆฌ๋ผ์„œ ์ฝ”๋“œ ๊ตฌ์กฐ๊ฐ€ ํˆฌ๋ช…ํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›€.
    • ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ƒ๊ฒจ๋„ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ ์ตœ์†Œํ™”๋จ.
  3. ํ…Œ์ŠคํŠธ ์šฉ์ด
    • ์˜์กด์„ฑ ์ฃผ์ž…์œผ๋กœ Mock์ด๋‚˜ Stub์„ ์ด์šฉํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ์‰ฌ์›Œ์ง.
    • ํ…Œ์ŠคํŠธ ์‹œ ์‹ค์ œ ๊ตฌํ˜„ ๋Œ€์‹  ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ ์„ฑ๋Šฅ ํ–ฅ์ƒ.
  4. ๊ฒฐํ•ฉ๋„ ๋‚ฎ์Œ
    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์ด ์•„๋‹Œ ์ถ”์ƒํ™”์— ์˜์กดํ•˜๋ฏ€๋กœ ํด๋ž˜์Šค ๊ฐ„ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์Œ.
    • ์ฝ”๋“œ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ์˜ํ–ฅ์ด ์ค„์–ด๋“ฆ.
  5. ํ™•์žฅ์„ฑ ๋ฐ ์œ ์—ฐ์„ฑ ์ข‹์Œ
    • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ์‹œ ๊ธฐ์กด ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ์ƒˆ๋กœ์šด ์˜์กด์„ฑ๋งŒ ์ฃผ์ž…ํ•˜๋ฉด ๋จ.

[๋‹จ์ ]

  1. ๋ณต์žก์„ฑ ์ฆ๊ฐ€
    • DI ์ปจํ…Œ์ด๋„ˆ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ ์‚ฌ์šฉ ์‹œ ์„ค์ • ๋ฐ ํ•™์Šต์ด ๋ฒˆ๊ฑฐ๋กœ์›Œ์ง.
    • ์ž‘์€ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๊ณผํ•œ ๋ฐฉ์‹์ผ ์ˆ˜ ์žˆ์Œ.
  2. ๋””๋ฒ„๊น… ์–ด๋ ค์›€
    • ๋Ÿฐํƒ€์ž„์— ์˜์กด์„ฑ ์ฃผ์ž…๋˜๋ฏ€๋กœ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ถ”์ ํ•˜๊ธฐ ์–ด๋ ค์›€.
  3. ์„ฑ๋Šฅ ์ €ํ•˜
    • DI ์ปจํ…Œ์ด๋„ˆ ์‚ฌ์šฉ ์‹œ ์˜์กด์„ฑ ์ƒ์„ฑ๊ณผ ์ฃผ์ž…์ด ๋Ÿฐํƒ€์ž„์— ์ด๋ฃจ์–ด์ ธ ๋ฏธ์„ธํ•œ ์„ฑ๋Šฅ ์ €ํ•˜ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.
  4. ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ๋–จ์–ด์ง
    • ์˜์กด์„ฑ ์ฃผ์ž… ๊ณผ๋„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ์ƒ์„ฑ์ž๋‚˜ ๋ฉ”์„œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋งŽ์•„์ ธ์„œ ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง.
    • DI ์ปจํ…Œ์ด๋„ˆ ์—†์ด ์ˆ˜๋™์œผ๋กœ ์ฃผ์ž…ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์žฅํ™ฉํ•ด์ง.
  5. ๊ตฌํ˜„ ์ดํ•ด ์–ด๋ ค์›€
    • DI ํŒจํ„ด์„ ์ฒ˜์Œ ์ ‘ํ•˜๊ฑฐ๋‚˜ ๊ฒฝํ—˜์ด ๋ถ€์กฑํ•œ ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๊ฐœ๋…๊ณผ ์ ์šฉ ๋ฐฉ๋ฒ•์ด ์–ด๋ ค์›€.

์˜์กด์„ฑ ์ฃผ์ž…์€ ํ™•์žฅ์„ฑ, ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ ๋“ฑ ์žฅ์ ์ด ์žˆ์ง€๋งŒ, ์ž‘์€ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ. ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ ์ ˆํžˆ ์ ์šฉํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•จ.


๐Ÿ–ฅ๏ธ DI ์˜ˆ์‹œ (C#)

using System;

namespace DependencyInjection;

// ํด๋ผ์ด์–ธํŠธ๋Š” ์ด ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•ด์„œ๋งŒ ์•Œ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์–ด๋–ค ํŠน์ • ๊ฒŒ์ž„ํŒจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€๋Š” ์•Œ์ง€ ๋ชปํ•จ.
interface IGamepadFunctionality {
    string GetGamepadName(); // ๊ฒŒ์ž„ํŒจ๋“œ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜
    void SetVibrationPower(float power); // ์ง„๋™ ์„ธ๊ธฐ๋ฅผ ์„ค์ •
}

// ๋‹ค์Œ ์„œ๋น„์Šค๋“ค์€ ์œ„์˜ ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•œ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์„ ์ œ๊ณต.
class XboxGamepad : IGamepadFunctionality {
    float vibrationPower = 1.0f; // ์ง„๋™ ์„ธ๊ธฐ ๊ธฐ๋ณธ๊ฐ’

    // Xbox ๊ฒŒ์ž„ํŒจ๋“œ์˜ ์ด๋ฆ„ ๋ฐ˜ํ™˜
    public string GetGamepadName() => "Xbox controller";

    // ์ง„๋™ ์„ธ๊ธฐ๋ฅผ ์„ค์ •ํ•˜๋ฉฐ, 0.0์—์„œ 1.0 ์‚ฌ์ด๋กœ ํด๋žจํ•‘
    public void SetVibrationPower(float power) => this.vibrationPower = Math.Clamp(power, 0.0f, 1.0f);
}

class PlaystationJoystick : IGamepadFunctionality {
    float vibratingPower = 100.0f; // ์ง„๋™ ์„ธ๊ธฐ ๊ธฐ๋ณธ๊ฐ’

    // PlayStation ๊ฒŒ์ž„ํŒจ๋“œ์˜ ์ด๋ฆ„ ๋ฐ˜ํ™˜
    public string GetGamepadName() => "PlayStation controller";

    // ์ง„๋™ ์„ธ๊ธฐ๋ฅผ ์„ค์ •ํ•˜๋ฉฐ, 0.0์—์„œ 100.0 ์‚ฌ์ด๋กœ ํด๋žจํ•‘ (์ž…๋ ฅ ๊ฐ’์— 100์„ ๊ณฑํ•จ)
    public void SetVibrationPower(float power) => this.vibratingPower = Math.Clamp(power * 100.0f, 0.0f, 100.0f);
}

class SteamController : IGamepadFunctionality {
    double vibrating = 1.0; // ์ง„๋™ ์„ธ๊ธฐ ๊ธฐ๋ณธ๊ฐ’

    // Steam ๊ฒŒ์ž„ํŒจ๋“œ์˜ ์ด๋ฆ„ ๋ฐ˜ํ™˜
    public string GetGamepadName() => "Steam controller";

    // ์ง„๋™ ์„ธ๊ธฐ๋ฅผ ์„ค์ •ํ•˜๋ฉฐ, 0.0์—์„œ 1.0 ์‚ฌ์ด๋กœ ํด๋žจํ•‘
    public void SetVibrationPower(float power) => this.vibrating = Convert.ToDouble(Math.Clamp(power, 0.0f, 1.0f));
}

// ์ด ํด๋ž˜์Šค๋Š” ์„œ๋น„์Šค๋ฅผ ์ œ๊ณต๋ฐ›๋Š” ํด๋ผ์ด์–ธํŠธ ์—ญํ• ์„ ํ•จ.
class Gamepad {
    IGamepadFunctionality gamepadFunctionality; // ์˜์กด์„ฑ์œผ๋กœ ์ œ๊ณต๋ฐ›์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ €์žฅ

    // ์„œ๋น„์Šค๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋˜๋ฉฐ, ์œ„ ํ•„๋“œ์— ์ €์žฅ๋จ.
    public Gamepad(IGamepadFunctionality gamepadFunctionality) => this.gamepadFunctionality = gamepadFunctionality;

    public void Showcase() {
        // ์ฃผ์ž…๋œ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉ
        var gamepadName = this.gamepadFunctionality.GetGamepadName(); // ๊ฒŒ์ž„ํŒจ๋“œ ์ด๋ฆ„ ๊ฐ€์ ธ์˜ค๊ธฐ
        var message = $"We're using the {gamepadName} right now, do you want to change the vibrating power?";
        Console.WriteLine(message);
    }
}

class Program {
    static void Main() {
        var steamController = new SteamController();

        // XboxController, PlaystationJoystick ๋“ฑ ๋‹ค๋ฅธ ๊ตฌํ˜„์ฒด๋„ ์ „๋‹ฌ ๊ฐ€๋Šฅ
        // Gamepad๋Š” ์–ด๋–ค ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€ ๋ชฐ๋ผ๋„ ๋จ.
        var gamepad = new Gamepad(steamController);

        gamepad.Showcase(); // ๊ฒŒ์ž„ํŒจ๋“œ ์ƒํƒœ ์ถœ๋ ฅ
    }
}


์ถœ์ฒ˜ :
๏ผŠ https://en.wikipedia.org/wiki/Dependency_injection#Advantages
๏ผŠ https://f-lab.kr/insight/dependency-injection-and-spring-framework-20240521


ยฉ 2024. All rights reserved.

Powered by Hydejack v9.2.1